Search

Custom Attribute Load Failure in GetAjaxFrameworkAssemblyAttribute by Jerod Venema

Closed
as Fixed Help for as Fixed

6
0
Sign in
to vote
Type: Bug
ID: 588777
Opened: 8/24/2010 12:05:48 PM
Access Restriction: Public
1
Workaround(s)
3
User(s) can reproduce this bug
Hey folks!

There's a minor bug in .NET 4 that causes problems when loading pages with a ScriptManager on the page. Within the System.Web.Extensions dll, in the System.Web.UI.AssemblyCache class, the method "GetAjaxFrameworkAssemblyAttribute" enumerates all the custom attributes in a given assembly. If, for some reason, one of those attributes is unavailable, this method fails and the application crashes.

See this search for a number of people running into the same problem:

http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=GetAjaxFrameworkAssemblyAttribute

The solution would be to simply wrap the call to GetCustomAttributes() in a try...catch block; if there's a problem getting an attribute for an unrelated DLL, it should not cause the application to crash.

Also, see this thread: http://groups.google.com/group/websync/browse_thread/thread/83c1f88abbb00b80?pli=1
Details (expand)

Visual Studio/Silverlight/Tooling version

.NET Framework 4

What category (if any) best represents this feedback?

 

Steps to reproduce

1) Download a "community edition" copy of WebSync (www.frozenmountain.com/websync)
2) Open the "Extensions" sample project in VS2010, allowing it to convert it to .NET 4
3) Add a ScriptManager tag to the default.aspx page
4) Run the project

Product Language

English

Operating System

Windows 7

Operating System Language

English

Actual results

Could not load file or assembly 'FM.WebSync.Extensions.ExtensionAttribute, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

Expected results

The dll "FM.WebSync.Extensions.ExtensionAttribute" has a single class that provides extension method support in .NET 2.0. It is NOT required in .NET 3.0+, since extension methods are native. However, since it was compiled with 2.0, the reference still exists in the DLL itself (although, as noted, no functionality is provided). The entire application should not crash.
File Attachments
0 attachments
Sign in to post a comment.
Posted by Marian Zaki on 1/31/2012 at 4:14 AM
Where should we put the code below?
Where to add the try and catch

public static AjaxFrameworkAssemblyAttribute GetAjaxFrameworkAssemblyAttribute(Assembly assembly)
{
    AjaxFrameworkAssemblyAttribute attribute = null;
    if (!_ajaxAssemblyAttributeCache.TryGetValue(assembly, out attribute))
    {
        foreach (Attribute attribute2 in assembly.GetCustomAttributes(false)) // <=== HERE
        {
            if (attribute2 is AjaxFrameworkAssemblyAttribute)
            {
                attribute = (AjaxFrameworkAssemblyAttribute) attribute2;
                break;
            }
        }
        _ajaxAssemblyAttributeCache.TryAdd(assembly, attribute);
    }
    return attribute;
Posted by Iulian Ionescu on 5/6/2011 at 6:54 AM
This bug still exists as of today!!
Here is where the error lies: In the ScriptManager constructor you are trying to find the DefaultAjaxAssembly and you call a procedure that scans all loaded assemblies looking for a certain attribute. The problem is that if the code that retrieves the attribute fails the entire code in the constructors fails and exists with the specific exception. This is where the problem is:

In System.Web.UI.AssemblyCache:


public static AjaxFrameworkAssemblyAttribute GetAjaxFrameworkAssemblyAttribute(Assembly assembly)
{
    AjaxFrameworkAssemblyAttribute attribute = null;
    if (!_ajaxAssemblyAttributeCache.TryGetValue(assembly, out attribute))
    {
        foreach (Attribute attribute2 in assembly.GetCustomAttributes(false)) // <=== HERE
        {
            if (attribute2 is AjaxFrameworkAssemblyAttribute)
            {
                attribute = (AjaxFrameworkAssemblyAttribute) attribute2;
                break;
            }
        }
        _ajaxAssemblyAttributeCache.TryAdd(assembly, attribute);
    }
    return attribute;
}

You must wrap that in a try{}catch{} block to prevent the entire code from crashing when the GetCustomAttributes fails on a certain library. In my case this was failing on a library called AxAcroPDFLib.dll because it had the following attribute:


[assembly: TypeLibraryTimeStamp("16.05.2006 21:31:20")]

Because of my locale that cannot be converted to a Date and so the whole code was crashing with a invalid string for Date kind of exception...

Iulian
Posted by Microsoft on 8/24/2010 at 5:05 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
Posted by Iulian Ionescu on 5/6/2011 at 6:58 AM
If you find yourself having this bug try to run this code from one of your pages, a page that does NOT have the ScriptManager on it. Put a breakpoint before the Catch and step through the loop until you get the exception. Note which assembly it is and what is the error. Either remove that assembly from your project, look for an updated one or attempt to fix the attribute yourself if you have access to its source code.


using System.Web.Hosting;
using System.Web.Compilation;
using System.Web.Script;
using System.Reflection;

protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            _ajaxAssemblyAttributeCache = new ConcurrentDictionary<Assembly, AjaxFrameworkAssemblyAttribute>();
            IEnumerable<Assembly> enumerable = null;
            if (HostingEnvironment.IsHosted)
            {
                enumerable = BuildManager.GetReferencedAssemblies().OfType<Assembly>();
            }
            else
            {
                enumerable = AppDomain.CurrentDomain.GetAssemblies();
            }
            //else
            //{
            //    enumerable = from assemblyInfo in RuntimeConfig.GetAppConfig().Compilation.Assemblies.OfType<AssemblyInfo>() select assemblyInfo.AssemblyInternal;
            //}
            foreach (Assembly assembly in enumerable)
            {
                AjaxFrameworkAssemblyAttribute ajaxFrameworkAssemblyAttribute = GetAjaxFrameworkAssemblyAttribute(assembly);
                if (ajaxFrameworkAssemblyAttribute != null)
                {
                    //break;
                }
            }
        }
        catch (Exception ex)
        {
            int x = 0;
        }
    }

    private ConcurrentDictionary<Assembly, AjaxFrameworkAssemblyAttribute> _ajaxAssemblyAttributeCache;


    private AjaxFrameworkAssemblyAttribute GetAjaxFrameworkAssemblyAttribute(Assembly assembly)
    {
        
        AjaxFrameworkAssemblyAttribute attribute = null;
        if (!_ajaxAssemblyAttributeCache.TryGetValue(assembly, out attribute))
        {
            foreach (Attribute attribute2 in assembly.GetCustomAttributes(false))
            {
                if (attribute2 is AjaxFrameworkAssemblyAttribute)
                {
                    attribute = (AjaxFrameworkAssemblyAttribute)attribute2;
                    break;
                }
            }
            _ajaxAssemblyAttributeCache.TryAdd(assembly, attribute);
        }
        return attribute;

    }