IHttpModule is an interface that contains two methods to implement: Init and Dispose. What is cool and useful about IHttpModules is that you register classes that implement this interface in the Web.Config file, and the code is called for every single HTTP call whether it is a postback—regular round trip to the server—or a callback—typically associated with asynchronous Ajax calls. In short, IHttpModule exists to let you insert code into every HTTP call in the pipeline.
To define an IHttpModule derive a class that implements the IHttpModule interface and register the module containing the class in the Web.Config in the <httpModules> section. What you elect to do in the module is up to you. You can catch Application errors in one place if you want to for instance, or you could hook into other Application events and handler other kinds of operations. Listing 1 shows an implementation of IHttpModule, and Listing 2 shows how to load the module in the Web.Config.
Listing 1: Custom IHttpModule that intercepts every HTTP request and in this case only tracks errors.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Diagnostics;
public class MyCustomModule : IHttpModule
{
public MyCustomModule()
{
}
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.Error += new EventHandler(context_Error);
}
void context_Error(object sender, EventArgs e)
{
try
{
HttpApplication application = (HttpApplication)sender;
Exception exception = application.Server.GetLastError();
// this would clear all exceptions -- which is interesting to see
// but a bad idea in practice
//application.Server.ClearError();
EventLog.WriteEntry("Application", exception.Message);
}
catch { }
}
#endregion
}
Listing 2: The custom IHtpModule is shown in bold font. (Some of the Web.Config items were stripped out by me to shorten the listing.)
<?xml version="1.0"?>
<!--
Note: As an alternative to hand editing this file you can use the
web admin tool to configure settings for your application. Use
the Website->Asp.Net Configuration option in Visual Studio.
A full list of settings and comments can be found in
machine.config.comments usually located in
\Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
<configSections>
</configSections>
<appSettings/>
<connectionStrings/>
<system.web>
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.
-->
<compilation debug="false">
<assemblies>
</assemblies>
</compilation>
<!--
The <authentication> section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
<authentication mode="Windows" />
<!--
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
<pages>
</pages>
<httpHandlers>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add type="MyCustomModule" name="MyCustomModule" />
</httpModules>
</system.web>
<system.codedom>
<compilers>
</compilers>
</system.codedom>
<!--
The system.webServer section is required for running ASP.NET AJAX under Internet
Information Services 7.0. It is not necessary for previous version of IIS.
-->
<system.webServer>
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
In Listing 1 the IHttpModule writes every exception to the EventLog. Clearly you could implement basic logging in the Global.asax file’s Application_Error, which is equivalent to what this IHttpModule is doing. Of course, even implementing an error logging handler is more portable because you could put it in a redistributable assembly and write once and use many times.
An interesting use of the IHttpModule is Developer Express’ ASPxHttpHandlerModule. The ASPxHttpHandlerModule works especially well with our Ajax-capable controls. Generally, Ajax calls don’t call a Web page’s Render part of the lifecycle, thus if an error occurs in an Ajax call an application appears to hang. If you register the ASPxHttpHandlerModule then you can choose between the default behavior of Ajax errors being sent to the client or page redirection. The ASPxHttpHandlerModule can be added to a project from the Smart tags menu of our controls.