Download Source Code Download HandlersAndModules.zip - 6.55 KB
Introduction
This article describes how Http modules and handlers are to be written and configured in IIS 7.5. The concept of a handler and module remains same, so dose there programming model. In this section we start off with the concept of a Http module and a Http handler, then talk about how to code them and finally describe the two methods available to configure them.
In case you have programmed Http modules and handlers in past you may skip upcoming sections and straightaway move to configuring Http modules and handlers.
What is a Module and what is a Handler?
In this section we attempt to describe a module and a handler, their differences and when to use each.
The primary job of an Http handler is to produce a http response (not html). This means a hander can churn out Html, an image or even an error code like 404, but these should adhere to http standards. A hander is mapped to a resource type on the server. Thus when we say we want a resource such as http://MyServer.Com/Image233.Image
or
http://MyServer.Com/Images.Image/Id=233
or
http://MyServer.Com/Images.Image/233
The fact that we are trying to access a .Image type of resource means there is a handler on the server side which handles requests associated with these resource types and produces a valid Http response.
The goal of a module in simplistic terms is provide support to incoming and outgoing Http requests and responses. This support may be done by tinkering the request or response such as changing the url or writing a response (such as a water mark or copy write in header’s / footers). It may be something which provides server side support such as associating cache objects or authentication of a request. It may be system support such as logging information to a database and so on.
A handler is associated with a particular type resource. It may be mapped to only a given resource. Handler mappings may also be restricted by a Http verb which means you may want to only work with GET requests ( for example if you Http handler is only supposed to send back images) or a POST request ( for example if you collect some data on the given handler)
A module is associated with every request in the Http pipeline. It provides decoration of incoming requests and outgoing responses. Any filtering based upon protocol type or resource extensions should be handled programmatically (for example if you want to put water marks on all your images and add text to all your Html responses then the fact that you will do this on GET requests of type .image(.jpg,.png etc) and .aspx, .htm, .html and so on must be coded in your module)
We should code a custom Http handler if and only if the resource type to be accessed is fairly customized and is a separate entity on you system The Http response generation logic weather visible or not is very different from a regular aspx pages. In these cases it should be observed that the request should not be part of a page lifecycle.
A http module should be used if you wish to write some common logic for all your requests and these requests may not always be part of a aspx request (hence you do not have access to a common base page).
IIS 7.5 configuration
With IIS 7.5 and beyond it is being tried that as far as possible the config definition should be available in the web.config file of an ASP.net web site. Both modules and handlers can be configured using the IIS wizard or by directly editing the web.config file.
The idea is that we should have less and less dependency on the IT team. It is also in line with the fact that applications which are deployed on a shared IIS server or cloud will not have direct access to the IIS admin control. Having entire configuration in web.config also means that there are no external steps for configuration.
In this article we will describe the details only for IIS 7.5 integrated pipeline mode because it is the opinion of the author that this is the way to go moving forward.
The Code
Writing Http Modules
Http module (the managed kind written in .net) implements IHTTPModule. This interface gears any class to be used as an Http module. The IHttpModule has one method Init. In this method using the HttpApplication various events of interest where the Http module may decorate the request or response may be added.
public class HeaderAndFooterModule :IHttpModule
void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
context.EndRequest += new EventHandler(context_EndRequest);
}
In the above given code the Begin request and end request have been hooked up to the module.
For this example only a hard coded header and footer are being added.
void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication httpApplication = (HttpApplication)sender;
httpApplication.Context.Response.Write("<h1>The header....</h1>");
}
void context_EndRequest(object sender, EventArgs e)
{
HttpApplication httpApplication = (HttpApplication)sender;
httpApplication.Context.Response.Write("<h6>The footer....</h6>");
}
We can hook up any event of interest. It should be noted that any incoming and outgoing request will be catered to using this module.
Configuring Http Modules
Http modules can be configured using the IIS both by editing the web.config file or using the IIS manager GUI. We will look at each of these techniques in this section.
Using web.config
<system.webServer>
<modules>
<add name="HeaderAndFooterModule" type="HeaderAndFooterModule" />
</modules>
</system.webServer>
In the configuration section of the web.config file a new section is added for <system.webServer>. This section contains details of configuring the IIS server in integrated pipeline mode.
The section module contains a list of all the modules each having a unique name and type containing the type name to access the class. This can include a full type name to access any arbitrary assembly.
Using IIS Manager
1. Open IIS Manager
2. Expand the node of your web application
3. Open the modules feature
<formulas /></formulas />
4. Click on add managed handler
5. Fill in the name and type of the module
Writing Http Handlers
Any managed http handler implements the IHTTPHandler interface.
public class TextHandler :IHttpHandler
The Http handler has a very important property IsReusable. The purpose of this property is to define if the instance of the Http handler can be shared or not. The IsReusable property should return true if and only is there is no field in the handler which can define the state. If we make IsReusable as false then the performance is slower.
bool IHttpHandler.IsReusable
{
get { return true; }
}
The other method of interest is Process request, the objective of this method is to generate any valid Http response (not html response).
void IHttpHandler.ProcessRequest(HttpContext context)
{
StringBuilder htmlText = new StringBuilder();
htmlText.Append("<html>");
htmlText.Append("<title>");
htmlText.Append("</title>");
htmlText.Append("<body>");
htmlText.Append("<h1>");
htmlText.Append("Sample Text");
htmlText.Append("</h1>");
htmlText.Append("</body>");
htmlText.Append("</html>");
context.Response.Write(htmlText.ToString());
}
Configuring Http Handlers
Configuration of Http handlers follows similar mechanism as modules. Handlers can be configured by using web.config or using the IIS manager.
Using web.config
<system.webServer>
<handlers>
<add name="TextHandler" path="*.Text" verb="*" type="TextHandler" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
In the system.webServer section add a handlers section. In this add a new handler. The name is a unique name for the handler. The path contains the path on the server. It can be wild card or an absolute path. In this example the value can be *.Text or Static.Text. The value of verb can be * or a comma separated set of verbs such as GET, POST, PUT, DELETE or any verbs used for this handler.
The type is the fully qualified name of the class in which the handler code is written. It should be noted that a precondition here is integratedMode.
Using IIS Manager
1. Open IIS Manager
2. Expand the node of your web application
3. Open the Handler Mapping feature
4. Click on Add managed handler
5. Add the various values
6.Click on request restrictions and add values for verbs
Some pitfalls
1. Session is not available – The HttpSessionState is a module in itself hence we should ensure that when creating a module we will not have access to Http Session.
2. Http request is read only – The various elements of the Http request such as query strings in modules are readonly. It should be noted that the url is not read only and you can create modules for Url rewrite.
3. Http handler IsReusable –The IsReusable property is a death trap for the novice programmer. Great care should be taken to decide the value of IsReusable. It should be noted that as far as possible we should try to keep our handler stateless in interest of performance.