Using Themes in ASP.NET loads System.Drawing namespace

Using the System.Drawing namespace is strongly discouraged in ASP.NET as it leads to a lot of performance/runtime problems.

Recently one of our customers reported an issue where we were getting GDI+ errors in a  normal ASP.NET application.

Exception type: System.Runtime.InteropServices.ExternalException
Message: GDI+ is not properly initialized (internal GDI+ error).
InnerException: <none>
StackTrace (generated):
    SP       IP       Function
    048CE1A0 7AE65963 System.Drawing.Bitmap..ctor(System.IO.Stream)
    048CE1C8 7AE31EAE System.Drawing.ToolboxBitmapAttribute..cctor()

StackTraceString: <none>
HResult: 80004005

The GDI+ calls were not something intentional, none of the application code contained any  reference to the System.Drawing namespace. But the namespace was getting loaded in the process as a result of applying a Theme to the page.

System.Reflection.CustomAttribute._CreateCaObject(Void*, Void*, Byte**, Byte*, Int32*)
System.Reflection.CustomAttribute.CreateCaObject(System.Reflection.Module, System.RuntimeMethodHandle, IntPtr ByRef, IntPtr, Int32 ByRef)
System.Reflection.CustomAttribute.GetCustomAttributes(System.Reflection.Module, Int32, Int32, System.RuntimeType, Boolean, System.Collections.IList)
System.Reflection.CustomAttribute.GetCustomAttributes(System.RuntimeType, System.RuntimeType, Boolean)
System.RuntimeType.GetCustomAttributes(System.Type, Boolean)
System.ComponentModel.ReflectTypeDescriptionProvider.ReflectGetAttributes(System.Type)
System.ComponentModel.ReflectTypeDescriptionProvider+ReflectedTypeData.GetAttributes()
System.ComponentModel.TypeDescriptor+TypeDescriptionNode+DefaultTypeDescriptor.System.ComponentModel.ICustomTypeDescriptor.GetAttributes()
System.ComponentModel.TypeDescriptor.GetAttributes(System.Type)
System.Web.UI.ThemeableAttribute.IsTypeThemeable(System.Type)
System.Web.UI.Control.ApplySkin(System.Web.UI.Page)
System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)

When an ASPX page has to load a Theme we loop through all Controls/Types on the page and check if we can apply the theme to it(IsTypeThemeable). This involves generating  a list of attributes for the Control/Type. Its a simple call to TypeDescriptor.GetAttributes method which results in each attribute being instantiated. And this is where the trouble starts.

Controls have a ToolboxBitmap attribute which is a picture representation of the control. Its a bitmap and this results in the unintentional loading of the System.Drawing namespace in the worker process.

Currently a fix is being worked on and should be released soon.

Bookmark and Share