SOLVED: “The type initializer for ‘System.Drawing.ToolboxBitmapAttribute’ threw an exception”

This exception has been plaguing our automated error reports inbox for a while:

System.TypeInitializationException: The type initializer for 'System.Drawing.ToolboxBitmapAttribute' threw an exception. 
  ---> System.Runtime.InteropServices.ExternalException: GDI+ is not properly initialized (internal GDI+ error).
  at System.Drawing.Bitmap..ctor(Stream stream)
  at System.Drawing.ToolboxBitmapAttribute..cctor()
  --- End of inner exception stack trace ---
  at System.Reflection.CustomAttribute._CreateCaObject(Void* pModule, Void* pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
  at System.Reflection.CustomAttribute.CreateCaObject(Module module, RuntimeMethodHandle ctor, IntPtr& blob, IntPtr blobEnd, Int32& namedArgs)
  at System.Reflection.CustomAttribute.GetCustomAttributes(Module decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes)
  at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit)
  at System.RuntimeType.GetCustomAttributes(Type attributeType, Boolean inherit)
  at System.ComponentModel.ReflectTypeDescriptionProvider.ReflectGetAttributes(Type type)
  at System.ComponentModel.ReflectTypeDescriptionProvider.ReflectedTypeData.GetAttributes()
  at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.DefaultTypeDescriptor.System.ComponentModel.ICustomTypeDescriptor.GetAttributes()
  at System.ComponentModel.TypeDescriptor.GetAttributes(Type componentType)
  at System.Web.UI.ViewStateModeByIdAttribute.IsEnabled(Type type)
  at System.Web.UI.Control.SaveViewStateRecursive()
  at System.Web.UI.Control.SaveViewStateRecursive()
  at System.Web.UI.Control.SaveViewStateRecursive()
  at System.Web.UI.Control.SaveViewStateRecursive()
  at System.Web.UI.Control.SaveViewStateRecursive()
  at System.Web.UI.Page.SaveAllState()
  at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

The page it occurs on is the login page of an ASP.NET WebForms app which happens to be the default.aspx page in the root of the site: a page that gets a lot of hits. It happened sporadically and was impossible to reproduce: likely some odd timing issue. But when it did happen, it brought the whole web app down.

There appears to be an official hotfix for System.Drawing.dll at http://support.microsoft.com/kb/975410. You will need to contact Microsoft Support for this though. Rather than use up one of our Microsoft Partner support hits, a quick, simple solution dawned on me.

Our solution

Looking at the stack trace, it’s clear that the issue occurs when the page’s ViewState is being serialised. Therefore, the solution (OK, more of a workaround) in our case was simply to disable ViewState on the page:

<@Page … EnableViewState="false" %>

Now this might not work for you because your page, or controls on your page may rely on ViewState. For example, if you have OnChange event handlers on textboxes: these rely on having the “before” stashed in ViewState. But we rarely use ViewState anywhere in the application, so it was especially galling that we’d left it enabled on one of the the busiest pages in the app.

Leave a comment