Once received and preprocessed by IIS, each ASP.NET request is forwarded to the ASP.NET worker environment and handled by the HTTP runtime pipeline. The HTTP runtime pipeline is a collection of components hosted by an instance of the IIS service host executable and orchestrated by the ASP.NET ISAPI module loaded inside of it. The ISAPI module first sets up a managed environment and then initializes the pipeline. Each ASP.NET request enters this pipeline as a HTTP packet and exits from the other end as a chunk of markup ready for the browser.
The HTTP pipeline consists of a number of special components known as HTTP modules. An HTTP module is essentially a repository of event handlers each executing some special task on the passing request. The progress of the request through the pipeline is controlled by an object known as the HTTP application. Among other things, this object fires a number of application-level events to listening components—including HTTP modules and the application's global.asax file.
The BeginRequest event occurs as soon as the HTTP pipeline begins to process the request; similarly, the EndRequest event is fired when all has been done and the markup is on its way to the browser. In between these two events, a number of others occur to spot important achievements of the request state. The AuthenticateRequest event occurs when the selected authentication HTTP module has determined the identity of the current user. The AuthorizeRequest event reaches your code when authorization assessment has been made. Note that in ASP.NET 2.0, most events also feature a post event, such as PostAuthenticateRequest and PostAuthorizeRequest. Needless to say, post events fire when the operation has been successfully terminated. ResolveRequestCache is the event fired when the pipeline checks whether the request can be served using any of the previously cached pages. If the requested page employs output caching, the cached markup is retrieved and served at this point. Next, session state is loaded from the selected storage medium and attached to the current request. Finally, the HTTP handler to serve the request is identified, loaded, and executed.
When the HTTP handler executes, the page goes through the familiar lifecycle that developers work with in the code-behind class—Page_Init, Page_Load, postback events rendering, and the like. The execution of the page's code is wrapped by two application-level events: PreRequestHandlerExecute and PostRequestHandlerExecute. The former event is fired immediately prior to executing the HTTP handler for the request. The latter event, instead, is raised when the handler has generated the response text.
The final set of events revolves around releasing session state and updating the page output cache, if enabled.
These global events can be handled in either of two ways—via ad hoc HTTP modules or through code added to the global.asax application file. As mentioned, an HTTP module is a component that you add to the pipeline when you need to set up functionality based on these events. For example, an HTTP module is useful to preprocess the query string of each request or to filter the output stream before it gets sent to the browser.
There is no big difference between using HTTP modules or global.asax handlers, as far as the functionality itself is concerned. However, an HTTP module can be enabled or disabled declaratively using the web.config file; a piece of code in global.asax is disabled or enabled through manual editing. In addition, a HTTP module can be reused across applications. Code in global.asax can only be copy-and-pasted in other applications.