共用方式為


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.

Bookmark and Share

Comments

  • Anonymous
    February 01, 2009
    PingBack from http://www.clickandsolve.com/?p=2673

  • Anonymous
    February 12, 2009
    If you implement custom health monitoring events in ASP.NET chances are that you should have worked with