Archive for June, 2009

How to determine if an ASP.NET OutputCacheModule is enabled for your application

No Comments »

I recently had an issue with an ASP.NET application concerning output caching. I thought output caching was configured correctly, but apparently pages weren’t being served from the cache. So, what do you do? Well, I decided to find out for real, whether the System.Web.Caching.OutputCacheModule was being run. When the OutputCacheModule is initialized it will register event handlers on the HttpApplication’s ResolveRequestCache and UpdateRequestCache events. Thus, I set out to determine who was subscribing to these events at runtime.

After spending some quality time with Reflector and the debugger I discovered that the HttpApplication uses a somewhat internal scheme to organize the registered event handlers. You can get to the datastructure containing the handlers through the HttpApplication.Events property of type EventHandlerList. However, in order to get to the desired delegate, you have to index this property with the correct key. In this case, the key is a private static readonly field of HttpApplication! Enter System.Reflection.

The key for getting at the ResolveRequestCache is called EventResolveRequestCache (likewise, for UpdateRequestCache it is called EventUpdateRequestCache). Hence, we may add the following code to Global.asax.cs to get to the subscribing HttpModules:

private IEnumerable GetResolveRequestCacheSubscribers()
{
    Type httpapptype = typeof(HttpApplication);
    FieldInfo f = httpapptype.GetField("EventResolveRequestCache",
                                                    BindingFlags.Static |
                                                    BindingFlags.NonPublic);
    object eventResulveRequestCacheKey = f.GetValue(this);
    Delegate dels = Events[eventResulveRequestCacheKey];
    if(dels == null)
        return Enumerable.Empty();
    else
        return (from d in dels.GetInvocationList()
                    where d.Target != null && d.Target is IHttpModule
                select d.Target as IHttpModule);
}

Enjoy