How to work with HttpModules in ASP.Net

HTTP modules intercept incoming requests and inject pre-processing logic in the ASP.Net request processing pipeline

HttpModule

HttpModule

There are two ways in which you can inject logic in the request pipeline of an ASP.NET application -- HttpHandlers and HttpModules. An HttpModule is a component that is part of the ASP.NET request processing pipeline and is called on every request that is made to your application.

Note that HttpModules can have access to the life cycle events of a request and hence they can be used to modify the response as well. HttpModules are generally used for plugging in the cross cutting concerns like security, logging, etc. in the request processing pipeline and can also be used for URL re-writing and even for creating custom headers in the response.

The MSDN states: "An HTTP module is an assembly that is called on every request that is made to your application. HTTP modules are called as part of the ASP.NET request pipeline and have access to life-cycle events throughout the request. HTTP modules let you examine incoming and outgoing requests and take action based on the request."

To create a custom HttpModule, you should create a class that implements the System.Web.IHttpModule interface. To create an HttpModule, follow these steps:

  1. Open Visual Studio IDE
  2. Click on File->New Project
  3. Create a class library project
  4. Add reference to System.Web assembly to this project
  5. Next, create a class inside this project that implements the IHttpModule interface
  6. Write a handler for the Init method to initialize your module and subscribe to one or more events
  7. Optionally, implement a Dispose method in your custom module

At first glance, our custom HttpModule looks like this:

public class IDGCustomHttpModule : IHttpModule

   {

       public void Dispose()

       {

           throw new NotImplementedException();

       }

       public void Init(HttpApplication context)

       {

           throw new NotImplementedException();

       }

   }

The following code snippet shows how you can subscribe to events in your custom http module.

public void Init(HttpApplication context)

       {

           context.BeginRequest += new EventHandler(OnBeginRequest);

           context.EndRequest += new EventHandler(OnEndRequest);            

           context.LogRequest += new EventHandler(OnLogRequest);

       }

Let’s now write the code for the OnLogRequest method. This method is intended to log the path or every request to a text file. Here’s how the OnLogRequest method should look like:

public void OnLogRequest(object sender, EventArgs e)

       {

           HttpContext context = ((HttpApplication)sender).Context;

           string filePath = @"D:\IDGLog.txt";

           using (StreamWriter streamWriter = new StreamWriter(filePath))

           {

               streamWriter.WriteLine(context.Request.Path);

           }

       }

The following code listing illustrates the complete custom Http module.

public class IDGCustomModule: IHttpModule

   {

       public void Init(HttpApplication context)

       {

           context.BeginRequest += new EventHandler(OnBeginRequest);

           context.EndRequest += new EventHandler(OnEndRequest);          

           context.LogRequest += new EventHandler(OnLogRequest);

       }

       public void OnLogRequest(object sender, EventArgs e)

       {

           HttpContext context = ((HttpApplication)sender).Context;

           string filePath = @"D:\IDGLog.txt";

           using (StreamWriter streamWriter = new StreamWriter(filePath))

           {

               streamWriter.WriteLine(context.Request.Path);

           }

       }

       public void OnBeginRequest(object sender, EventArgs e)

       {

           //Write your custom code here

       }

       public void OnEndRequest(object sender, EventArgs e)

       {

           //Write your custom code here

       }

       public void Dispose()

       {

           //Write your custom code here to dispose any objects if needed

       }

   }

The next step is to use the custom HTTP module. To do this, create another project (this time, an ASP.Net application project). Now, build the solution and add reference to the custom HTTP module we just created. Next, you would need to register the custom HTTP module in the web.config file. The following code snippet illustrates how the custom HTTP module can be registered.

<system.webServer>

   <modules>

   <add name="CustomHttpModule" type="IDGModule.IDGCustomModule, IDGCustomModule" />

   </modules>

</system.webServer>

And, that’s all you need to do to use your custom Http module.

When using a synchronous HTTP module, the thread would not be released till the request processing completes. This can become a major performance bottleneck when your custom HTTP module needs to perform long running I/O bound operations. To solve this, you can take advantage of asynchronous programming to implement an asynchronous HTTP module as well. This would ensure that the performance of your application doesn't degrade when your HTTP module needs to do lot of processing. Asynchronous programming helps in better usage of available resources.

To implement asynchrony in your custom HTTP module, you would want to leverage the EventHandlerTaskAsyncHelper class available as part of .NET Framework 4.5. The following code snippet illustrates how you can take advantage of this class to subscribe to events in the Init method of your custom HTTP module. Note that the LogRequest method should return an instance of type Task.

public void Init(HttpApplication context)

       {

           EventHandlerTaskAsyncHelper asyncHelperObject = new EventHandlerTaskAsyncHelper(LogRequest);

           context.AddOnPostAuthorizeRequestAsync(asyncHelperObject.BeginEventHandler, asyncHelperObject.EndEventHandler);

       }

Here’s the complete code listing of the asynchronous version of our custom Http module.

public class IDGCustomModule: IHttpModule

   {

       public void Init(HttpApplication context)

       {

           EventHandlerTaskAsyncHelper asyncHelperObject = new EventHandlerTaskAsyncHelper(LogRequest);

           context.AddOnPostAuthorizeRequestAsync(asyncHelperObject.BeginEventHandler, asyncHelperObject.EndEventHandler);

       }

       private async Task LogRequest(object sender, EventArgs e)

       {

           HttpContext context = ((HttpApplication)sender).Context;

           string filePath = @"D:\IDGLog.txt";

            using (StreamWriter streamWriter = new StreamWriter(filePath,true))

           {

               await streamWriter.WriteLineAsync(context.Request.Path);

           }

       }

   }

This article is published as part of the IDG Contributor Network. Want to Join?

To comment on this article and other InfoWorld content, visit InfoWorld's LinkedIn page, Facebook page and Twitter stream.
From CIO: 8 Free Online Courses to Grow Your Tech Skills
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.