The Two Interceptors: HttpModule and HttpHandlers

Introduction

Many times we want to implement pre-processing logic before a request hits the IIS resources. For instance you would like to apply security mechanism, URL rewriting, filter something in the request, etc. ASP.NET has provided two types of interception HttpModule and HttpHandler. This article walks through it.

The Problem

Many times we need to inject some kind of logic before the page is requested. Some of the commonly used pre-processing logics are stat counters, URL rewriting, authentication / authorization and many more. We can do this in the code behind but then that can lead to lot of complication and tangled code. The code behind will not solve the purpose because in some implementations like authorization, we want the logic to execute before it reaches the resource. ASP.NET provides two ways of injecting logic in the request pipeline HttpHandlers and HttpModules.

HttpHandler – The Extension Based Preprocessor

HttpHandler help us to inject pre-processing logic based on the extension of the file name requested. So when a page is requested, HttpHandler executes on the base of extension file names and on the base of verbs. For instance, you can visualize from the figure below how we have different handlers mapped to file extension. We can also map one handler to multiple file extensions. For instance, when any client requests for file with extension ‘GIF’ and ‘JPEG’, handler3 pre-processing logic executes.

HttpModule – The Event Based Preprocessor

HttpModule is an event based methodology to inject pre-processing logic before any resource is requested. When any client sends a request for a resource, the request pipeline emits a lot of events as shown in the figure below:

Below is a detailed explanation of the events. We have just pasted this from here.

  • BeginRequest: Request has been started. If you need to do something at the beginning of a request (for example, display advertisement banners at the top of each page), synchronize this event.
  • AuthenticateRequest: If you want to plug in your own custom authentication scheme (for example, look up a user against a database to validate the password), build a module that synchronizes this event and authenticates the user in a way that you want to.
  • AuthorizeRequest: This event is used internally to implement authorization mechanisms (for example, to store your access control lists (ACLs) in a database rather than in the file system). Although you can override this event, there are not many good reasons to do so.
  • PreRequestHandlerExecute: This event occurs before the HTTP handler is executed.
  • PostRequestHandlerExecute: This event occurs after the HTTP handler is executed.
  • EndRequest: Request has been completed. You may want to build a debugging module that gathers information throughout the request and then writes the information to the page.

We can register these events with the HttpModules. So when the request pipe line executes depending on the event registered, the logic from the modules is processed.

The Overall Picture of Handler and Modules

Now that we have gone through the basics, let’s understand what is the Microsoft definition for handler and modules to get the overall picture.

Reference: INFO: ASP.NET HTTP Modules and HTTP Handlers Overview

“Modules are called before and after the handler executes. Modules enable developers to intercept, participate in, or modify each individual request. Handlers are used to process individual endpoint requests. Handlers enable the ASP.NET Framework to process individual HTTP URLs or groups of URL extensions within an application. Unlike modules, only one handler is used to process a request”.

 

HTTP Modules

Modules are called before and after the handler executes. Modules enable developers to intercept, participate in, or modify each individual request. Modules implement the IHttpModule interface, which is located in the System.Web namespace.

Available Events

An HttpApplicationclass provides a number of events with which modules can synchronize. The following events are available for modules to synchronize with on each request. These events are listed in sequential order:

  • BeginRequest: Request has been started. If you need to do something at the beginning of a request (for example, display advertisement banners at the top of each page), synchronize this event.
  • AuthenticateRequest: If you want to plug in your own custom authentication scheme (for example, look up a user against a database to validate the password), build a module that synchronizes this event and authenticates the user how you want to.
  • AuthorizeRequest: This event is used internally to implement authorization mechanisms (for example, to store your access control lists (ACLs) in a database rather than in the file system). Although you can override this event, there are not many good reasons to do so.
  • ResolveRequestCache: This event determines if a page can be served from the Output cache. If you want to write your own caching module (for example, build a file-based cache rather than a memory cache), synchronize this event to determine whether to serve the page from the cache.
  • AcquireRequestState: Session state is retrieved from the state store. If you want to build your own state management module, synchronize this event to grab the Session state from your state store.
  • PreRequestHandlerExecute: This event occurs before the HTTP handler is executed.
  • PostRequestHandlerExecute: This event occurs after the HTTP handler is executed.
  • ReleaseRequestState: Session state is stored back in the state store. If you are building a custom session state module, you must store your state back in your state store.
  • UpdateRequestCache: This event writes output back to the Output cache. If you are building a custom cache module, you write the output back to your cache.
  • EndRequest: Request has been completed. You may want to build a debugging module that gathers information throughout the request and then writes the information to the page.

The following events are available for modules to synchronize with for each request transmission. The order of these events is non-deterministic.

  • PreSendRequestHeaders: This event occurs before the headers are sent. If you want to add additional headers, you can synchronize this event from a custom module.
  • PreSendRequestContent: This event occurs when the Response.Flush method is called. If you want to add additional content, you can synchronize this event from a custom module.
  • Error: This event occurs when an unhandled exception occurs. If you want to write a custom error handler module, synchronize this event.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s