Handling Public Events

Any public event raised by the HttpApplication class is supported using the syntax Application_EventName. For example, a handler for the Error event can be declared protected void Application_Error(Object sender, EventArgs e). Support is also provided for asynchronous events.

There are three categories of public events: application events raised by HttpApplication, module events raised by HttpModules, and asynchronous events raised by HTTPApplication.

Application Events

The following tables show the events raised by HttpApplication during the life of an application. The first table shows the events raised before the application executes. The events are listed in the order in which they occur.

Event Description
BeginRequest Signals a new request; guaranteed to be raised on each request.
AuthenticateRequest Signals that the request is ready to be authenticated; used by the security module.
AuthorizeRequest Signals that the request is ready to be authorized; used by the security module.
ResolveRequestCache Used by the output cache module to short-circuit the processing of requests that have been cached.
AcquireRequestState Signals that per-request state should be obtained.
PreRequestHandlerExecute Signals that the request handler is about to execute. This is the last event you can participate in before the HttpHandler for this request is called.

The next table shows the events raised after an application has returned. The events are listed in the order in which they occur.

Event Description
PostRequestHandlerExecute Signals that the HttpHandler has completed processing the request.
ReleaseRequestState Signals that the request state should be stored because the application is finished with the request.
UpdateRequestCache Signals that code processing is complete and the file is ready to be added to the ASP.NET cache.
EndRequest Signals that all processing has finished for the request. This is the last event called when the application ends.

In addition, there are three per-request events that can be raised in a nondeterministic order. They are shown in the table below.

Event Description
PreSendRequestHeaders Signals that HTTP headers are about to be sent to the client. This provides an opportunity to add, remove, or modify the headers before they are sent.
PreSendRequestContent Signals that content is about to be sent to the client. This provides an opportunity to modify the content before it is sent.
Error Signals an unhandled exception.

Module Events

You can connect to (hook) events that are published by the HttpModules defined in a configuration. For example, Machine.config declares the following default modules for all applications.

<httpModules>
    <add name="OutputCache" type="System.Web.Caching.OutputCacheModule, .../>
    <add name="Session" type="System.Web.SessionState.SessionStateModule, .../>
    <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule, .../>
    <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule .../>
    <add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule .../>
    <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule, .../>
    <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule, .../>
</httpModules>

In any of these classes, look for the public events they define. You can hook them in Global.asax using the syntax ModuleName**_On**EventName. For example, the Start event of the SessionStateModule module is declared protected void Session_Start(Object sender, EventArgs e) in Global.asax. You can use the syntax Session_OnStart in a <script runat=server> block in an ASP.NET application file to define an event handler for the Start event of the SessionStateModule as follows.

<script language="VB" runat="server">
    Sub Session_OnStart()
        ' Session startup code goes here.
    End Sub
</script>

Note You can just as easily use the same ModuleName**_On**EventName syntax for hooking events in your own custom modules, as long as they are declared in the configuration file for your application.

Asynchronous Events

Event handlers for asynchronous events in HttpApplication must be explicitly connected by calling the AddAsynchronousEventName method in Global.asax. For example, an asynchronous event handler for the OnPostRequestHandlerExecuteAsync event would register for the event by calling the method AddOnPostRequestHandlerExecuteAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler). The shortcut Application**_On**EventName syntax is for synchronous events only. Declarations for the HttpApplication asynchronous events are as follows.

void OnAcquireRequestStateAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnAuthenticateRequestAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnAuthorizeRequestAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnBeginRequestAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnEndRequestAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnPostRequestHandlerExecuteAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnPreRequestHandlerExecuteAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnReleaseRequestStateAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnResolveRequestCacheAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnUpdateREquestCacheAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)

An example of a code block you can include in Global.asax to create an asynchronous handler for the OnPostRequestHandlerExecuteAsync event follows.

<%@ language=c# %>
<%@ import namespace="System.Threading" %>
<script runat=server>
public override void Init() {
    // Connect the asynchronous event PreRequestHandlerExecuteAsync.
    AddOnPreRequestHandlerExecuteAsync(
        new BeginEventHandler(this.BeginPreHandlerExecute), 
        new EndEventHandler(this.EndPreHandlerExecute));
}
IAsyncResult BeginPreHandlerExecute(Object source, EventArgs e, AsyncCallback cb, Object extraData) {
    AsynchOperation asynch = new AsynchOperation(cb, Context, extraData);
    asynch.StartAsyncWork();
    return asynch;
}
void EndPreHandlerExecute(IAsyncResult ar) {
}
class AsynchOperation : IAsyncResult {
    private bool _completed;
    private Object _state;
    private AsyncCallback _callback;
    private HttpContext _context;

    bool IAsyncResult.IsCompleted { get { return _completed; } }
    WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } }
    Object IAsyncResult.AsyncState { get { return _state; } }
    bool IAsyncResult.CompletedSynchronously { get { return false; } }

    public AsynchOperation(AsyncCallback callback, HttpContext context, Object state) {
        _callback = callback;
        _context = context;
        _state = state;
        _completed = false;
    }

    public void StartAsyncWork() {
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomething), null /*workItemState*/);
    }

    private void DoSomething(Object workItemState) {
        _context.Items["PreHandlerExecute"] = "Hello World from Async PreHandleExecute!";
        _completed = true;
        _callback(this);
    }
}
</script>

See Also

HTTP Runtime Support | HttpModules | Custom HttpModule Example | Handling and Raising Events