HttpModules: The Replacement for ISAPI
In Chapter 6, we mentioned how IIS can pass requests to an ISAPI program, which can then interpret the request according to how it was programmed. ASP.NET itself runs as an ISAPI program. The old version of Active Server Pages ran this way as well. Although this is certainly a powerful interface, it's not easy to implement.
To make this request processing easy, ASP.NET offers HttpModules as a way to hook into the request and response. Although HttpHandlers handle a request for a particular file extension or path specific to the request and get a reference to the HttpContext object, an HttpModule gets involved at the application level, first to touch the request on the way into the server, and then to touch it on the response's return to the browser. An HttpModule gets a reference to the HttpApplication object and is capable of assigning event handlers to the application events.
ASP.NET already has several HttpModules that may be in play by default in your application. For example, if you're using Forms Authentication, a class called System.Web.Security.FormsAuthenticationModule sets up the authentication information for the request. A class called System.Web.Caching.OutputCacheModule processes requests for cached pages and user controls. Listing 8.6 shows the httpModules section of machine.config. An HttpModule must be listed in web.config or machine.config to be used.
Listing 8.6. The httpModules section of machine.config
[View full width]
<httpModules>
<clear />
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
<add name="Session" type="System.Web.SessionState.SessionStateModule" />
<add name="SessionID" type="System.Web.SessionState.SessionIDModule" />
<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="RoleManager" type="System.Web.Security
.RoleManagerModule" />
<add name="UrlAuthorization" type="System.Web.Security
.UrlAuthorizationModule" />
<add name="FileAuthorization" type="System.Web.Security
.FileAuthorizationModule" />
<add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" />
<add name="Profile" type="System.Web.Profile.ProfileModule" />
<add name="PageCountersModule" type="System.Web.PageCountersModule" />
<add name="SqlBatchModule" type="System.Web.DataAccess.SqlBatchModule" />
</httpModules>
You can further distinguish the difference between HttpHandlers and HttpModules just by looking at the name of these components and thinking about the scope of their activity. For example, we saw earlier that the HttpHandler PageHandlerFactory handled requests specifically for ASP.NET pages, but it had nothing to do with the execution of application-level code. Here we have an HttpModule called SessionIDModule. Based on its name, you can infer that this module keeps track of session activity and that this process is not limited to a page requestit also calls for Web services or any other ASP.NET resource, even the .jpg requests in our previous HttpHandler.
The IHttpModule interface is similarly easy to implement, having only two members, as shown in Listing 8.7.
Listing 8.7. A class implementing IHttpModule
C#
public class MyHttpModule : IHttpModule
{
public void Init(HttpApplication application)
{
// do something here
}
public void Dispose()
{
}
}
VB.NET
Public Class MyHttpModule
Implements IHttpModule
Public Sub Init(application As HttpApplication)
' do something here
End Sub
Public Sub Dispose()
End Sub
End Class
The Init() method of the interface provides our hook to the application. Through this reference to the application, we can wire up event handlers to application events, similarly to the manner in which we wired up control and page events in Listing 7.6. We'll wire up some new event handlers in our next code listing.
If there is some kind of clean up work to do when the application terminates, we can do it in the Dispose() method. You might delete temporary files or database records in this method, for example.