Omer van Kloeten's .NET Zen

Programming is life, the rest is mere details

News

Omer van Kloeten's Facebook profile

Get Firefox

.NET Resources

Articles :: CodeDom

Articles :: nGineer

Culture

Projects

Help! My Web Application Throws an Insane Amount of TypeLoadExceptions!

One of the first things I noticed when I started debugging our web application was that at load I got an insane amount of these:

A first chance exception of type 'System.TypeLoadException' occurred in System.Web.dll
A first chance exception of type 'System.TypeLoadException' occurred in System.Web.dll
A first chance exception of type 'System.TypeLoadException' occurred in System.Web.dll
...

After digging into the code, I found out that during the loading process of controls, ASP.NET tries to find the type that matches a certain tag. The following code piece from System.Web.UI.NamespaceTagNameToTypeMapper (line 82):

Type type = null; 

// If loading the type from the assembly depends on a referenced assembly that cannot
// be loaded, we should throw the actual exception, instead of later reporting a more
// generic error saying the type was not found (Devdiv 138674) 
try {
    type = _assembly.GetType(typeName, true /*throwOnError*/, true /*ignoreCase*/); 
} 
catch (System.IO.FileNotFoundException) {
    throw; 
}
catch (System.IO.FileLoadException) {
    throw;
} 
catch (BadImageFormatException) {
    throw; 
} 
catch {
    // For all other exceptions, such as when the type is not present in the assembly, 
    // we ignore the exception so that we can continue to check other assemblies to look
    // for the type.
}
return type;

What the hell?! This is a horrible bottleneck!

What's the solution, you ask? Well, it's simple - just tell ASP.NET ahead of time where your controls are with the @ Register directive. For instance:

<%@ Register Assembly="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" 
             Namespace="System.Web.UI.WebControls" TagPrefix="wc" %>

This gives ASP.NET a little hint, telling it that if it wants controls with the wc tag prefix, it should look for them in the System.Web.UI.WebControls namespace in the System.Web assembly. Then all you have to do is to mark all of the controls that come from that namespace in that assembly with that specific prefix, as such:

<wc:Literal ID="Something" runat="server"></wc:Literal>

And that's that. No more annoying exceptions.

Make sure to use the full assembly name in the @ Register directive, otherwise you'll get a System.IO.FileNotFoundException thrown when ASP.NET can't find the assembly.

One more thing that's important to note is that if you have only a few of these, set your web.config's compilation element's batch attribute to false, which means ASP.NET will load pages on demand. This way you'll know the culprit page when you hit it for the first time, rather than have the exception thrown when the whole application starts.

[Update: An application-wide solution would be to use the system.web / pages / controls element in the web.config to declare prefixes for all of your controls, rather than at the single page level:

<configuration>
  <system.web>
    <pages>
      <controls>
        <add tagPrefix="wc" namespace="System.Web.UI.WebControls"
assembly="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

And thanks to Ofer Bar from my team for the tip.]

Comments

Dave Transom said:

Hi Omar,

Interesting find.

Are you saying that:

<wc:Literal ID="Something" runat="server" />

Would replace the normal syntax?

<asp:Literal ID="Something" runat="server" />

What are the implications performance-wise? Quicker start up due to less exceptions having to be handled?

# April 17, 2008 11:43 PM

Omer van Kloeten said:

Hey Dave,

First of all, the name's Omer, not Omar :)

What you're doing by using the custom prefix is taking away ASP.NET's need to find the control by itself in all loaded assemblies by explicitly telling it where the control is. That would drastically increase load time, because you'd have saved the time it takes to throw exceptions for each control you use in your application and for each assembly that control may be in.

# April 18, 2008 2:55 AM

Ana said:

Hello,

I have this same problem and I tried to fix it has you say, but it continues to give me a lots of same error.

On my web.config is

<pages>

<controls>

 <add tagPrefix="aspx" namespace="System.Web.UI"   assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

 <add tagPrefix="asp" namespace="System.Web.UI.WebControls"  assembly="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

</controls>

I'm using Ajax and I'm using a Iframe to capture diferente pages im my WebApplication. I don't know what more I can do. Can you help me?

Thanks very much

# June 17, 2008 1:34 PM

Omer van Kloeten said:

You should not use 'asp', since it's a reserved prefix with two possibilities, so it might throw these exceptions. Use some other prefix instead and make sure that no control's tag in your application uses 'asp' as a prefix.

# June 17, 2008 2:52 PM

Ana said:

Thank you very much!

I used another tagprefix as you say and it resolved this problem. Thanks once more!

# June 18, 2008 5:55 AM

Greg said:

Thanks for the great information.  Do you know if there's been a bug report filed about this?  Do you think this problem would noticeably impact performance?

This workaround around hides the "asp" prefix from intellisense, but any controls that are dragged from the toolbox still sport the "asp" prefix.

# June 18, 2008 5:05 PM

Omer van Kloeten said:

It's not a bug, but rather 'by-design' and I gave up on trying to file 'by-design' bugs a long time ago. They just don't get fixed.

Performance will only be impacted if you use batch="false" and even then only once per page, since this happens when ASP.NET compiles the pages. Not a big hit, but very annoying when starting to debug a project with a LOT of aspx files.

# June 18, 2008 5:44 PM

Greg said:

Thanks, Omer.  I just started a new application with VS 2008 that has pretty stringent performance requirements and was worried this would affect it.  You've been a big help.

# June 19, 2008 11:10 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)