WebBaseEvent.Raise method fails in Application_Start event with a NullReferenceException on IIS 7.0
If you implement custom health monitoring events in ASP.NET chances are that you should have worked with WebBaseEvent or WebErrorEvent classes and used the WebBaseEvent.Raise() method to fire those events. Recently an interesting issue related to this WebBaseEvent.Raise() was brought to my notice.
Suppose you have a custom event class something like
public class MyWebBaseEvent : WebBaseEvent
{
public MyWebBaseEvent(string message, object eventSource, int eventCode)
: base(message, eventSource, eventCode)
{
}
public MyWebBaseEvent(string message, object eventSource, int eventCode, int eventDetailCode)
: base(message, eventSource, eventCode, eventDetailCode)
{
}
public override void Raise()
{
base.Raise();
}
}
And in the global.asax you are firing this event as follows
void Application_Start(objectsender, EventArgs e)
{
// Code that runs on application startup
System.Web.Management.WebBaseEvent.Raise(newMyWebBaseEvent("Test message", this, 2147483646));
}
You also need a Listener to this event something like this EventLogProvider
<eventMappings>
<add name="All Custom Events" type="System.Web.Management.WebBaseEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="2147483631" endEventCode="2147483647"/>
</eventMappings>
<rules>
<add name="All Custom Events Default" eventName="All Custom Events" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>
</rules>
Now this will work fine on IIS 6.0. It will also work fine in IIS 7.0 if you application pool is running in Classic Mode. But if your application pool is using the Integrated Pipeline Mode the above code will fail with the following exception
Server Error in '/HealthMonitoringTest' Application.
--------------------------------------------------------------------------------
Request is not available in this context
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: Request is not available in this context
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[HttpException (0x80004005): Request is not available in this context]
System.Web.HttpContext.get_Request() +11161416
ASP.global_asax.Application_Start(Object sender, EventArgs e) +112
[HttpException (0x80004005): Request is not available in this context]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +4165105
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +205
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +336
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +350
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +382
[HttpException (0x80004005): Request is not available in this context]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11288390
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +88
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4331556
This exception occurs because we are using the WebBaseEvent.Raise() method in the Application_Start event. If you check the Exception Details it is complaining about the Request not being available.
The WebBaseEvent.Raise() method internally references the Request object from HttpContext. One of the design changes with IIS 7.0 is that HttpContext.Current.Request will not be populated in the Application_Start event (Integrated pipeline mode). As a result of the Request not being available the WebBaseEvent.Raise() starts failing.
You can work around this issue by assigning a dummy Request object to HttpContext.Current.Context.
We are currently working on a fix for this issue and should be released shortly as KB 962351.
Comments
Anonymous
February 01, 2009
PingBack from http://www.clickandsolve.com/?p=2673Anonymous
February 12, 2009
If you implement custom health monitoring events in ASP.NET chances are that you should have worked with