Sunday, October 19, 2014

Asp.net Handlers and Modules

HTTP Handlers and HTTP Modules 

HttpModule allows you to intercept the request (before it is handled by its handler) and response generated. It can modify both request/response if needed. ASP.NET sessions, profiles, authentication etc is also implemented as HttpModule - these module inspects the request and attach necessary context (e.g. session state based on session cookie) to the request. Such functionality is difficult to achieve via aspx code behind.
HttpHandler is the one responsible for handling the request i.e. to generate HTTP response which often (but not always) means generating some html. The page class (base for aspx) is nothing but http handler (so are other end points such as asmx, ashx, axd). The raw handler (ashx) is useful when you need absolute control over response generation - it would be possible to use aspx instead but then it would unnecessarily involve all default page/control machinery (view-state, post-date, control tree etc).
An ASP.NET HTTP handler is the process (frequently referred to as the "endpoint") that runs in response to a request made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page through the page handler. You can create your own HTTP handlers that render custom output to the browser.
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.
This topic contains:

Scenarios


Typical uses for custom HTTP handlers include the following:
  • RSS feeds   To create an RSS feed for a Web site, you can create a handler that emits RSS-formatted XML. You can then bind a file name extension such as .rss to the custom handler. When users send a request to your site that ends in .rss, ASP.NET calls your handler to process the request.
  • Image server   If you want a Web application to serve images in a variety of sizes, you can write a custom handler to resize images and then send them to the user as the handler's response.
Typical uses for HTTP modules include the following:
  • Security   Because you can examine incoming requests, an HTTP module can perform custom authentication or other security checks before the requested page, XML Web service, or handler is called. In Internet Information Services (IIS) 7.0 running in Integrated mode, you can extend forms authentication to all content types in an application.
  • Statistics and logging   Because HTTP modules are called on every request, you can gather request statistics and log information in a centralized module, instead of in individual pages.
  • Custom headers or footers   Because you can modify the outgoing response, you can insert content such as custom header information into every page or XML Web service response.

Features


HTTP handler and module features include the following:
  • The IHttpHandler and IHttpModule interfaces are the starting point for developing handlers and modules.
  • The IHttpAsyncHandler interface is the starting point for developing asynchronous handlers.
  • Custom handler and module source code can be put in the App_Code folder of an application, or it can be compiled and put in the Bin folder of an application.
  • Handlers and modules developed for use in IIS 6.0 can be used in IIS 7.0 with little or no change. For more information, see Moving an ASP.NET Application from IIS 6.0 to IIS 7.0.
  • Modules can subscribe to a variety of request-pipeline notifications. Modules can receive notification of events of the HttpApplication object.
  • In IIS 7.0, the request pipeline is integrated with the Web server request pipeline. HTTP modules can be used for any request to the Web server, not just ASP.NET requests.

Background


HTTP Handlers

An ASP.NET HTTP handler is the process that runs in response to a request that is made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page handler.
The ASP.NET page handler is only one type of handler. ASP.NET includes several other built-in handlers such as the Web service handler for .asmx files.

Built-in HTTP Handlers in ASP.NET

ASP.NET maps HTTP requests to HTTP handlers based on a file name extension. Each HTTP handler can process individual HTTP URLs or groups of URL extensions in an application. ASP.NET includes several built-in HTTP handlers, as listed in the following table.
Handler

ASP.NET page handler (*.aspx)
The default HTTP handler for all ASP.NET pages.
Web service handler (*.asmx)
The default HTTP handler for Web service pages created
 as .asmx files in ASP.NET.
Generic Web handler (*.ashx)
The default HTTP handler for all Web handlers that do
not have a UI and that include the @ WebHandler directive.
Trace handler (trace.axd)
A handler that displays current page trace information.
For details, see How to: View ASP.NET Trace Information with the Trace Viewer.

Creating a Custom HTTP Handler

To create a custom HTTP handler, you create a class that implements the IHttpHandler interface to create a synchronous handler. Alternatively, you can implement IHttpAsyncHandler to create an asynchronous handler. Both handler interfaces require that you implement the IsReusable property and the ProcessRequest method. The IsReusable property specifies whether the IHttpHandlerFactory object (the object that actually calls the appropriate handler) can put the handler in a pool and reuse it to increase performance. If the handler cannot be pooled, the factory must create a new instance of the handler every time that the handler is needed.
The ProcessRequest method is responsible for processing individual HTTP requests. In this method, you write the code that produces the output for the handler.
HTTP handlers have access to the application context. This includes the requesting user's identity (if known), application state, and session information. When an HTTP handler is requested, ASP.NET calls the ProcessRequest method of the appropriate handler. The code that you write in the handler's ProcessRequest method creates a response, which is sent back to the requesting browser.

Mapping a File Name Extension

When you create a class file as your HTTP handler, the handler can respond to any file name extension that is not already mapped in IIS and in ASP.NET. For example, if you are creating an HTTP handler for generating an RSS feed, you can map your handler to the .rss file name extension. In order for ASP.NET to know which handler to use for your custom file name extension, in IIS you must map the extension to ASP.NET. Then in the application, you must map the extension to the custom handler.
By default, ASP.NET maps the file name extension .ashx to an HTTP handler. If you add the @ WebHandler directive to a class file, ASP.NET automatically maps the .ashx file name extension to the default HTTP handler. This is similar to the way ASP.NET maps the .aspx file name extension to the ASP.NET page handler when the @ Page directive is used. Therefore, if you create an HTTP handler class that has the file name extension .ashx, the handler is automatically registered with IIS and ASP.NET.
If you want to create a custom file name extension for a handler, you must explicitly register the extension with IIS and ASP.NET. The advantage of not using the .ashx file name extension is that the handler is then reusable for different extension mappings. For example, in one application the custom handler might respond to requests that end in .rss. In another application, it might respond to requests that end in .feed. As another example, the handler might be mapped to both file name extensions in the same application, but might create different responses based on the extension.
The process for registering a handler's custom file name extension is different in IIS 7.0 and in earlier versions of IIS. For more information, see How to: Register HTTP Handlers and How to: Configure an HTTP Handler Extension in IIS.

Asynchronous and Synchronous HTTP Handlers

An HTTP handler can be either synchronous or asynchronous. A synchronous handler does not return until it finishes processing the HTTP request for which it is called. An asynchronous handler runs a process independently of sending a response to the user. Asynchronous handlers are useful when you must start an application process that might be lengthy and the user does not have to wait until it finishes before receiving a response from the server.
Asynchronous HTTP handlers enable you to start an external process, such as a method call to a remote server. The handler can then continue processing without waiting for the external process to finish. While an asynchronous HTTP handler is processing, ASP.NET puts the thread that would ordinarily be used for the external process back into the thread pool until the handler receives a callback from the external process. This can prevent thread blocking and can improve performance because only a limited number of threads can execute at the same time. If many users request synchronous HTTP handlers that rely on external processes, the operating system can run out of threads, because many threads are blocked and are waiting for an external process.
When you create an asynchronous handler, you must implement the IHttpAsyncHandler interface. You must also implement the BeginProcessRequest method in order to initiate an asynchronous call that processes individual HTTP requests. In addition, you must implement the EndProcessRequest method to run cleanup code when the process ends.

Custom IHttpHandlerFactory Classes

The IHttpHandlerFactory class receives requests and is responsible for forwarding a request to the appropriate HTTP handler. You can create a custom HTTP handler factory by creating a class that implements the IHttpHandlerFactory interface. A custom handler factory can give you finer control over how HTTP requests are processed by creating different handlers based on run-time conditions. For example, with a custom HTTP handler factory, you can instantiate one HTTP handler for a file type if the HTTP request method is PUT, and another if the method is GET.
To register a custom extension for a handler factory, follow the steps for registering a custom extension for a handler. For an example of creating and registering a handler factory, see Walkthrough: Creating and Registering HTTP Handler Factories.

HTTP Modules

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 request pipeline and have access to life-cycle events throughout the request. HTTP modules therefore let you examine incoming requests and take action based on the request. They also let you examine the outgoing response and modify it.
In IIS 6.0, the ASP.NET request pipeline is separate from the Web server request pipeline. In IIS 7.0, the ASP.NET request pipeline and the Web server request pipeline can be integrated into a common request pipeline. In IIS 7.0, this is referred to as Integrated mode. The unified pipeline has several benefits for ASP.NET developers. For example, it lets managed-code modules receive pipeline notifications for all requests, even if the requests are not for ASP.NET resources. However, if you want, you can run IIS 7.0 in Classic mode, which emulates ASP.NET running in IIS 6.0. For more information, see ASP.NET Application Life Cycle Overview for IIS 7.0.
ASP.NET HTTP modules are like ISAPI filters because they are invoked for all requests. However, they are written in managed code and are fully integrated with the life cycle of an ASP.NET application. You can put custom module source code in the App_Code folder of your application, or you can put compiled custom modules as assemblies in the Bin folder of an application.
ASP.NET uses modules to implement various application features, which includes forms authentication, caching, session state, and client script services. In each case, when those services are enabled, the module is called as part of a request and performs tasks that are outside the scope of any single page request. Modules can consume application events and can raise events that can be handled in the Global.asax file. For more information about application events, see ASP.NET Application Life Cycle Overview for IIS 5.0 and 6.0 and ASP.NET Application Life Cycle Overview for IIS 7.0.
NoteNote
HTTP modules differ from HTTP handlers. An HTTP handler returns a response to a request that is identified by a file name extension or family of file name extensions. In contrast, an HTTP module is invoked for all requests and responses. It subscribes to event notifications in the request pipeline and lets you run code in registered event handlers. The tasks that a module is used for are general to an application and to all requests for resources in the application.

How HTTP Modules Work

Modules must be registered to receive notifications from the request pipeline. The most common way to register an HTTP module is in the application's Web.config file. In IIS 7.0, the unified request pipeline also enables you to register a module in other ways, which includes through IIS Manager and through the Appcmd.exe command-line tool. For more information, see Configuring Handler Mappings in IIS 7.0 and Start Appcmd.exe.
When ASP.NET creates an instance of the HttpApplication class that represents your application, instances of any modules that have been registered are created. When a module is created, its Init method is called and the module initializes itself. For more information, see ASP.NET Application Life Cycle Overview for IIS 5.0 and 6.0 and ASP.NET ASP.NET Application Life Cycle Overview for IIS 7.0.
In a module's Init method, you can subscribe to various application events such as BeginRequest or EndRequest by binding the events to methods in the module.
For modules that operate in the IIS 7.0 integrated pipeline, you should register event handlers in the Init method.
When application events are raised, the appropriate method in your module is called. The method can perform whatever logic is required, such as checking authentication or logging request information. During event handling, the module has access to the Context property of the current request. This enables you to redirect the request to an alternative page, modify the request, or perform any other request manipulation. For example, if the module checks authentication, the module might redirect to a login or error page if the credentials are not correct. Otherwise, when the module's event handler has finished running, ASP.NET calls the next process in the pipeline. This might be another module or might be the appropriate HTTP handler (such as an .aspx file) for the request.

HTTP Modules versus Global.asax Files

You can implement much of the functionality of a module in the application's Global.asax file, which enables you to respond to application events. However, modules have an advantage over the Global.asax file because they are encapsulated and can be created one time and used in many different applications. By adding them to the global assembly cache and registering them in the Machine.config file, you can reuse them across applications. For more information, see Global Assembly Cache.
NoteNote
In IIS 7.0, the integrated pipeline enables managed modules to subscribe to pipeline notifications
 for all requests, not just requests for ASP.NET resources. Event handlers in the Global.asax file are
invoked only for notifications during requests for resources in the application. Custom modules in
Integrated mode can be explicitly scoped to receive event notifications only for requests to the

 application. Otherwise, custom modules receive event notification for all requests to the application.
 If the precondition attribute of the add element of the modules section is set to "managedHandler",
 the module is scoped to the application.
The advantage of using the Global.asax file is that you can handle other registered events such as Session_Start and Session_End. In addition, the Global.asax file enables you to instantiate global objects that are available throughout the application.
You should use a module whenever you must create code that depends on application events, and when the following conditions are true:
  • You want to re-use the module in other applications.
  • You want to avoid putting complex code in the Global.asax file.
  • The module applies to all requests in the pipeline (IIS 7.0 Integrated mode only).
You should add code in the Global.asax file whenever you must create code that depends on application events and you do not have to reuse it across applications. You can also use the Global.asax file when you have to subscribe to events that are not available to modules, such as Session_Start.

Creating an HTTP Module

The general process for writing an HTTP module is as follows:
For information about how to move a module from an application that is running in IIS 6.0 or earlier versions to an application that runs on in IIS 7.0, see Moving an ASP.NET Application from IIS 6.0 to IIS 7.0.


Class Reference


The following table lists the key server classes for the HTTP modules and HTTP handlers.
Used to create a custom HTTP module by implementing the
interface and then registering the module in the Web.config file.
Used to create a custom synchronous HTTP handler by creating a
class that implements the interface.
Used to create a custom, asynchronous HTTP handler by
creating a class that implements the interface.

The Two Interceptors: HttpModule and HttpHandlers


4 Mar 2009 CPOL
The two interceptors: HttpModule and HttpHandlers

Table of Contents

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.
For the last few days, I have been writing and recording videos in design patterns, UML, FPA, Enterprise blocks and lot more. You can watch the videos here.
You can download my 400 .NET FAQ EBook from here.

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 andHttpModules.

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.
“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”.

Steps to Implement HttpHandlers

Step 1

HttpHandlers are nothing but classes which have pre-processing logic implemented. So the first thing is to create a class project and reference System.Web namespace and implement the IHttpHandler interface as shown in the below code snippet. IHttpHandler interface has two methods which needs to be implemented; one is the ProcessRequest and the other is the IsResuable. In the ProcessRequest method, we are just entering the URL into the file and displaying the same into the browser. We have manipulated the context response object to send the display to the browser.
using System;
using System.Web;
using System.IO;
namespace MyPipeLine
{
public class clsMyHandler : IHttpHandler
{
public void ProcessRequest(System.Web.HttpContext context)
{
context.Response.Write("The page request is " + context.Request.RawUrl.ToString());
StreamWriter sw = new StreamWriter(@"C:\requestLog.txt",true);
sw.WriteLine("Page requested at " + DateTime.Now.ToString() + 
   context.Request.RawUrl); sw.Close();
}
public bool IsReusable
{
get
{
return true;
}
}
}

Step 2

In step 2, we need to make an entry of HttpHandlers tag. In the tag, we need to specify which kind of extension requested will invoke our class.
<system.web>
<httpHandlers>
<add verb="*" path="*.Shiv,*.Koirala" type="MyPipeLine.clsMyHandler, MyPipeLine"/>
</httpHandlers>
</system.web>
Once done, request for page name with extension ‘Shiv’ and you should see a display as shown below. So what has happened is when the IIS sees that request is for a ‘.shiv’ page extension, it just calls the clsMyHandler class pre-processing logic.

Steps to Implement HttpModule

Step 1

As discussed previously, HttpModule is an event pre-processor. So the first thing is to implement theIHttpModule and register the necessary events which this module should subscribe. For instance, we have registered in this sample for BeginRequest and EndRequest events. In those events, we have just written an entry on to the log file.
public class clsMyModule : IHttpModule
{
public clsMyModule()
{}
public void Init(HttpApplication objApplication)
{
// Register event handler of the pipe line
objApplication.BeginRequest += new EventHandler(this.context_BeginRequest);
objApplication.EndRequest += new EventHandler(this.context_EndRequest);
}
public void Dispose()
{
}
public void context_EndRequest(object sender, EventArgs e)
{
StreamWriter sw = new StreamWriter(@"C:\requestLog.txt",true);
sw.WriteLine("End Request called at " + DateTime.Now.ToString()); sw.Close();
}
public void context_BeginRequest(object sender, EventArgs e)
{
StreamWriter sw = new StreamWriter(@"C:\requestLog.txt",true);
sw.WriteLine("Begin request called at " + DateTime.Now.ToString()); sw.Close();
}
}

Step 2

We need to enter those module entries into the HttpModule tag as shown in the below code snippet:
<httpModules>
<add name="clsMyModule" type="MyPipeLine.clsMyModule, MyPipeLine"/>
</httpModules>

The Final Output

If you run the code, you should see something like this in the RequestLog.txt. The above example is not so practical. But it will help us understand the fundamentals.
Begin request called at 11/12/2008 6:32:00 PM
End Request called at 11/12/2008 6:32:00 PM
Begin request called at 11/12/2008 6:32:03 PM
End Request called at 11/12/2008 6:32:03 PM
Begin request called at 11/12/2008 6:32:06 PM
End Request called at 11/12/2008 6:32:06 PM
Begin request called at 11/12/2008 8:36:04 PM
End Request called at 11/12/2008 8:36:04 PM
Begin request called at 11/12/2008 8:37:06 PM
End Request called at 11/12/2008 8:37:06 PM
Begin request called at 11/12/2008 8:37:09 PM
End Request called at 11/12/2008 8:37:09 PM
Begin request called at 11/12/2008 8:37:38 PM
Page requested at 11/12/2008 8:37:38 PM/WebSiteHandlerDemo/Articles.shiv
End Request called at 11/12/2008 8:37:38 PM

Reference

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

    Implementing HTTPHandler and HTTPModule in ASP.NET


    27 Feb 2012 CPOL
    This article aims at understanding the role of HTTPHandler and HTTPModule in ASP.NET applications.

    Introduction

    This article aims at understanding the role of HTTPHandler and HTTPModule in ASP.NET applications. We will try to work on a basic example to see how these can be implemented.

    Background

    ASP.NET handles all the HTTP requests coming from the user and generates the appropriate response for it. ASP.NET framework knows how to process different kind of requests based on extension, for example, It can handle request for .aspx.ascx and .txt files, etc. When it receives any request, it checks the extension to see if it can handle that request and performs some predefined steps to serve that request.
    Now as a developer, we might want to have some of our own functionality plugged in. We might want to handle some new kind of requests or perhaps we want to handle an existing request ourselves to have more control on the generated response, for example, we may want to decide how the request for .jpg or .gif files will be handled. Here, we will need an HTTPHandler to have our functionality in place.
    There are also some scenarios where we are ok with the way ASP.NET is handling the requests but we want to perform some additional tasks on each request, i.e., we want to have our tasks execute along with the predefined steps ASP.NET is taking on each request. If we want to do this, we can have HTTPModule in place to achieve that.
    So from the above discussion, it is clear that HTTPHandlers are used by ASP.NET to handle the specific requests based on extensions. HTTPModule, on the other hand, is used if we want to have our own functionality working along with the default ASP.NET functionality. There is one Handler for a specific request but there could be N number of modules for that.

    Using the Code

    Let us try to understand these two concepts by writing a small application for each. What we will do is we will try to have a mechanism where we can process the web pages with extension like .bspx and .cspx. Although this is a very unrealistic scenario, a similar concept is used to have search engine friendly URLs so perhaps it's not that realistic either.
    Note: The HTTPHandler example here is just for demonstration purpose, I am not recommending the use ofHTTPHandlers for something that I am about to do now. HTTPHandlers should ideally be used to customize the handling of existing MIME types and not for serving search engine friendly URLs or non standard URLs.

    Implementing the HTTPHandler

    So with our problem definition, let us try to see how we can handle the request for .cspx pages usingHTTPHandlers. First we need to have the handler class with us, so let us create the handler class.
    public class CspxHandler :IHttpHandler
    {
        public bool IsReusable
        {
            get { return false; }
        }
    
        public void ProcessRequest(HttpContext context)
        {
    
        }
    }
    The class should have a method ProcessRequest and a property called IsReusable. The property tells whether this handler can be reused or not and the method will be called whenever a request for that type comes. But wait, Where have we defined the type of request where this handler should be invoked? This can be defined either in IIS, if we have a handler common to all the sites running on that server or we can configure it inweb.config file, if the handler is specific for a website. Let's do that in web.config file for now.
    <httpHandlers>
        <add verb="*" path="*.cspx" type="CspxHandler"/>
    </httpHandlers>
    Here we registered our handler to specify that if any request for .cspx file comes, it should be forwarded to our handler.
    Now, since we don't have any "real" files with .cspx extension, what we will do is we will handle the request for.cspx and in turn push the user to the corresponding .aspx file.
    public class CspxHandler :IHttpHandler
    {
        public bool IsReusable
        {
            get { return false; }
        }
    
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
    
            if (context.Request.RawUrl.Contains(".cspx"))
            {
                string newUrl = context.Request.RawUrl.Replace(".cspx", ".aspx");
                context.Server.Transfer(newUrl);
            }
        }
    }
    Whenever a request for .cspx file comes, we will handle it in our handler and show the corresponding .aspx file instead. Let's see how it works.
    Note: I have also changed the startup page name to Default.cspx but there is no page like that. I want my handler to handle that and show me the actual default page.

    Important: I reiterate, This example is just for illustration. This is not how HTTPHandlers should be used at all.HTTPHandlers should ideally be used to customize the handling of existing MIME types.
    Well the pages seems to be working fine and the user will see .cspx URL for his request. But there is one problem. The way we wrote our handler is not good to handle the postback. If I add a button on any of these pages and do a postback, the original URLs will be visible. So it is not a good solution to the problem but it sure demonstrated the way Handlers can be used.

    Implementing the HTTPModule

    How do we solve the problem we just saw. Well, our application needed URL rewriting and HTTPHandlers are a bad solution for that and should never be used for that. So perhaps the guys using this technique to have search friendly URLs should rethink their strategy. SO how can we solve this problem really.
    Let us look at the requirement again, All we needed was to show the user URLs which are different than the real URLs and process the real URLs internally. So we don't need custom handlers, we are ok with the way ASP.NET engine is handling these requests but we need custom activities to be done during the processing phase. So it looks like we can solve it using HTTPModule.
    So let's go ahead and write an HttpModule that will:
    1. Check for file extension on request.
    2. If it finds a .bspx extension it changes it to .aspx (or find real URLS if we are implementing search friendly URLs)
    3. It will pass the request to the default handler, since the page is still aspx.
    4. Once the response is generated, it will write back the original .bspx URL to users browser.
    public class MyBModule : IHttpModule
    {
        public void Dispose()
        {
    
        }
    
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
            context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
            context.EndRequest += new EventHandler(context_EndRequest);
            context.AuthorizeRequest += new EventHandler(context_AuthorizeRequest);
        }
    
        void context_AuthorizeRequest(object sender, EventArgs e)
        {
            //We change uri for invoking correct handler
            HttpContext context = ((HttpApplication)sender).Context;
    
            if (context.Request.RawUrl.Contains(".bspx"))
            {
                string url = context.Request.RawUrl.Replace(".bspx", ".aspx");
                context.RewritePath(url);
            }
        }
    
        void context_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            //We set back the original url on browser
            HttpContext context = ((HttpApplication)sender).Context;
    
            if (context.Items["originalUrl"] != null)
            {
                context.RewritePath((string)context.Items["originalUrl"]);
            }
        }
    
        void context_EndRequest(object sender, EventArgs e)
        {
            //We processed the request
        }
    
        void context_BeginRequest(object sender, EventArgs e)
        {
            //We received a request, so we save the original URL here
            HttpContext context = ((HttpApplication)sender).Context;
    
            if (context.Request.RawUrl.Contains(".bspx"))
            {
                context.Items["originalUrl"] = context.Request.RawUrl;
            }
        }
    }
    Also we need to register our module so that it can be invoked, we will do that in our web.config file.
    <httpModules>
        <add name="MyBModule" type="MyBModule" />
    </httpModules>
    And now let's run the application:

    So here we solved the problem of URL reverting back to the original on postback. This is also the ideal way of doing that.

    Points of Interest

    In this article, we saw how we can implement a basic HTTPHandler and HTTPModule. We saw each of their roles in page processing frameworks. We worked on an example that tried to solve the URL rewriting first the wrong way by using HTTPHandler (but we understood how to write HTTPhandler) and then the right way of doing URL rewriting using HTTPModule (we got to understand that too.
    The emphasis of this article was solely on understanding how we can have HTTPHandlers and HTTPModulesworking. The example is a little unrealistic and perhaps a little misleading too but since I made that point really clear, it shouldn't be a problem.
    Before wrapping up, there is one last thing that we should know about handlers. It is also possible to handle the request asynchronously. ASP.NET provides a mechanism for creating asynchronous handler and then increases the performance of a web page (implements the IHttpAsyncHandler do that).

    History

    • 25 Feb 2012: Implementing HTTPHandlers and HTTPModules in ASP.NET

      Difference between ASP.NET HttpHandler and HttpModule

      By Reeta Singh Lodhi  Blogs .NET 4.5  Oct 14, 2011
      In this blog we will see what are http handlers and modules in .Net. And in which condition which one is suitable.
      • 1
      • 3
      • 35776

      In this blog we will see what are http handlers and modules. And in which condition which one is suitable. For that first we need to understand when user request application resource to web server, what happened? The user requests for a resource on web server. The web server examines the file name extension of the requested file, and determines which ISAPI extension should handle the request. Then the request is passed to the appropriate ISAPI extension. For example when an .aspx page is requested it is passed to ASP.Net page handler. Then Application domain is created and after that different ASP.Net objects like Httpcontext, HttpRequest, HttpResponse are created. Then instance of HttpApplication is created and also instance of any configured modules. One can register different events of HttpApplication class like BeginRequest, AuthenticateRequest, AuthorizeRequest, ProcessRequest etc.
      HTTP Handler
      HTTP Handler is the process which runs in response to a HTTP request. So whenever user requests a file it is processed by the handler based on the extension. So, custom http handlers are created when you need to special handling based on the file name extension. Let's consider an example to create RSS for a site. So, create a handler that generates RSS-formatted XML. Now bind the .rss extension to the custom handler.
      HTTP Modules
      HTTP Modules are plugged into the life cycle of a request. So when a request is processed it is passed through all the modules in the pipeline of the request. So generally http modules are used for:
      Security: For authenticating a request before the request is handled.
      Statistics and Logging: Since modules are called for every request they can be used for gathering statistics and for logging information.
      Custom header:  Since response can be modified, one can add custom header information to the response.
    • HTTP Handlers and HTTP Modules in ASP.NET

      By Mansoor Ahmed Siddiqui
      In the Internet world, Web servers serve resources that have been put on the Internet and provide other services like security, logging, etc.
      Hands On: Building Your Own Watson Powered Application on Bluemix
      At the beginning of the Internet era, clients' needs were very limited; .htm files were often satisfactory. As time passed, however, clients' requirements extended beyond the functionality contained in .htm files or static files.
      Developers needed a way to extend or complement the functionality of Web servers. Web server vendors devised different solutions, but they all followed a common theme: "Plug some component into the Web server". All Web server complement technologies allowed developers to create and plug in components for enhancing Web server functionality. Microsoft came up with ISAPI (Internet Server API); Netscape came up with NSAPI (Netscape Server API), etc.
      ISAPI is an important technology that allows us to enhance the capabilities of an ISAPI-compliant Web server (IIS is an ISAPI-compliant Web server). The following components serve this purpose:
      • ISAPI Extensions
      • ISAPI Filters
      ISAPI extensions are implemented by using Win32 DLLs. You can think of an ISAPI extension as a normal application. ISAPI extensions are the target of http requests. That means you must call them to activate them. For example, the following URL calls the store.dll ISAPI extension and passes two values to it:
      http://www.myownwebsite.com/Store.dll?sitename=15seconds&location=USA
      Think of an ISAPI filter as just that: a filter. It sits between your Web server and the client. Every time a client makes a request to the server, it passes through the filter.
      Clients do not specifically target the filter in their requests, rather, clients simply send requests to the Web server, and then the Web server passes that request to the interested filters.
      Filters can then modify the request, perform some logging operations, etc.
      It was very difficult to implement these components because of the complexities involved. One had to use C/C++ to develop these components, and for many, development in C/C++ is a pain.
      So what does ASP.NET offer to harness this functionality? ASP.NET offers HttpHandlers and HttpModules.
      Before going into the details of these components, it is worth looking at the flow of http requests as it passes through the HTTP modules and HTTP handlers.
      Setting up the Sample Applications
      I have created the following C# projects, which demonstrate different components of the application.
      • NewHandler (HTTP handler)
      • Webapp (Demonstrates HTTP handler)
      • SecurityModules (HTTP module)
      • Webapp2 (Demonstrated HTTP module)
      To install the applications:
      • Extract all the code from the zip file below.
      • Create two virtual directories named webapp and webapp2; point these directories to the actual physical folders for the Webapp and Webapp2 web applications.
      • Copy the Newhandler.dll file from the NewHandler project into the bin directory of webapp web application.
      • Copy the SecurityModules.dll file from the SecurityModules project into the bin directory of webapp2 web application.
      ASP.NET Request Processing
      ASP.NET request processing is based on a pipeline model in which ASP.NET passes http requests to all the modules in the pipeline. Each module receives the http request and has full control over it. The module can play with the request in any way it sees fit. Once the request passes through all of the HTTP modules, it is eventually served by an HTTP handler. The HTTP handler performs some processing on it, and the result again passes through the HTTP modules in the pipeline.
      The following figure describes this flow.

      Figure 1
      Notice that during the processing of an http request, only one HTTP handler will be called, whereas more than one HTTP modules can be called.
      Http Handlers
      HTTP handlers are the .NET components that implement the System.Web.IHttpHandler interface. Any class that implements the IHttpHandler interface can act as a target for the incoming HTTP requests. HTTP handlers are somewhat similar to ISAPI extensions. One difference between HTTP handlers and ISAPI extensions is that HTTP handlers can be called directly by using their file name in the URL, similar to ISAPI extensions.
      HTTP handlers implement the following methods.
      Method NameDescription
      ProcessRequestThis method is actually the heart of all http handlers. This method is called to process http requests.
      IsReusableThis property is called to determine whether this instance of http handler can be reused for fulfilling another requests of the same type. HTTP handlers can return either true or false in order to specify whether they can be reused.
      These classes can be mapped to http requests by using the web.config or machine.config file. Once that is done, ASP.NET will instantiate http handler whenever the corresponding request comes in. We will see how to specify all of these details in web.config and/or machine.config files.
      ASP.NET also supports the creation of http handlers by means of the IHttpHandlerFactory interface. ASP.NET provides the capability of routing http requests to an object of the class that implements the IHttpHandlerFactory interface. Here, ASP.NET utilizes the Factory design pattern. This pattern provides an interface for creating families of related objects without specifying their concrete classes. In simple terms, you can consider such a class as a factory that creates http handler objects depending on the parameters passed to it. We don't have to specify a particular http handler class to instantiate; http handler factory takes care of it. The benefit of this is if in the future the implementation of the object that implements the IHttpHandler interface changes, the consuming client is not affected as long as the interface remains the same.
      These are following methods in IHttpHandlerFactory interface:
      Method NameDescription
      GetHandlerThis method is responsible for creating the appropriate handler and returns the reference out to the calling code (the ASP.NET runtime). Handler object returned by this method should implement the IHttpHandler interface.
      ReleaseHandlerThis method is responsible for releasing the http handler once request processing is complete. The implementation of the factory decides what it should do. Factory implementation can either actually destroy the instance or return it to a pool for future requests.
      Registering HTTP Handlers and HTTP Handler Factories in Configuration Files
      ASP.NET maintains its configuration information in the following configuration files:
      • machine.config
      • web.config
      machine.config file contains the configuration settings that apply to all the Web applications installed on that box.
      web.config file is specific to each Web application. Each Web application can have its own web.config file. Any sub directory of a Web application may have its own web.config file; this allows them to override the settings imposed by the parent directories.
      We can use <httpHandlers> and <add> nodes for adding HTTP handlers to our Web applications. In fact the handlers are listed with <add> nodes in between <httpHandlers> and </httpHandlers> nodes. Here is a generic example of adding an HTTP handler:
      1. <httpHandlers>
      2. <add verb="supported http verbs" path="path" type="namespace.classname, assemblyname" />
      3. <httpHandlers>
      4.  
      In the above XML,
      • The verb attribute specifies the HTTP verbs supported by the handler. If the handler supports all of the HTTP verbs, simply use "*", otherwise list the supported verbs in a comma separated list. So if your handler supports only HTTP GET and POST, then verb attribute will be "GET, POST".
      • The path attribute specifies the path or wildcard specification of the files for which this handler will be invoked. For example, if you want your handler to be called only when test.xyz file is requested, then the path attribute will contain "test.xyz"; similarly if you want your handler called for any file having .xyz extension, the path attribute will contain "*.xyz".
      • The type attribute specifies the actual type of the handler or handler factory in the form of a combination of namespace, class name and assembly name. ASP.NET runtime first searches the assembly DLL in the application's bin directory and then searches in the Global Assembly Cache (GAC).
      Use of HTTP Handlers by the ASP.NET Runtime
      Believe it or not, ASP.NET uses HTTP handlers for implementing a lot of its own functionality. ASP.NET uses handlers for processing .aspx, .asmx, .soap and other ASP.NET files.
      The following is the snippet from the machine.config file:
      1. <httpHandlers>
      2. <add verb="*" path="trace.axd" type="System.Web.Handlers.TraceHandler"/>
      3. <add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>
      4. <add verb="*" path="*.ashx" type="System.Web.UI.SimpleHandlerFactory"/>
      5. <add verb="*" path="*.config" type="System.Web.HttpForbiddenHandler"/>
      6. <add verb="GET,HEAD" path="*" type="System.Web.StaticFileHandler"/>
      7. . . . . . .
      8. . . . . . .
      9. </httpHandlers>
      10.  
      You can see in the above configuration that all the requests for .aspx files are processed by the System.Web.UI.PageHandlerFactory class. Similarly all the requests for .config and other files, which should not be directly accessible to the clients, are handled by the System.Web.HttpForbiddenHandler class. As you might have already guessed, this class simply returns an error to the client stating that these kinds of files are not served.
      Implementing HTTP Handlers
      Now we will see how to implement an HTTP handler. So what should our new handler do? Well, as I stated above, handlers are mostly used for adding new functionalities to Web servers; therefore, we will create a handler that handles new types of files, files that have a .15seconds extension. Once we implement this handler and register it in the web.config file of our Web application, all requests for .15seconds files will be handled by this new handler.
      You might be thinking about the use of such a handler. Well, what if you want to introduce a new kind of server scripting language or dynamic server file such as asp, aspx? You can write your own handler for this. Similarly, what will you do if you want to run Java servlets, JSPs and other server side Java components on IIS? One way of doing this is to install some ISAPI extension like Allaire or Macromedia Jrun. Or you can write your own HTTP handler. Although it is a difficult task for third-party vendors like Allaire and Macromedia, it is a very attractive option because their HTTP handlers will have access to all the new functionalities exposed by the ASP.NET runtime.
      Steps involved in implementing our HTTP handler are as follows:
      1. Write a class which implements IHttpHandler interface
      2. Register this handler in web.config or machine.config file.
      3. Map the file extension (.15seconds) to ASP.NET ISAPI extension DLL (aspnet_isapi.dll) in Internet Services Manager.
      Step1
      Create a new C# Class Library project in Visual Studio.NET and name it "MyHandler". Visual Studio.NET will automatically add a class named "Class1.cs" into the project. Rename it "NewHandler"; open this class in the code window and change the class name and constructor name to "NewHandler".
      The following is the code for the NewHandler class.
      1. using System;
      2. using System.Web;
      3. namespace MyHandler
      4. {
      5. /// <summary>
      6. /// Summary description for NewHandler.
      7. /// </summary>
      8. public class NewHandler : IHttpHandler
      9. {
      10. public NewHandler()
      11. {
      12. //
      13. // TODO: Add constructor logic here
      14. //
      15. }
      16. #region Implementation of IHttpHandler
      17. public void ProcessRequest(System.Web.HttpContext context)
      18. {
      19. HttpResponse objResponse = context.Response ;
      20. objResponse.Write("<html><body><h1>Hello 15Seconds Reader ") ;
      21. objResponse.Write("</body></html>") ;
      22. }
      23. public bool IsReusable
      24. {
      25. get
      26. {
      27. return true;
      28. }
      29. }
      30. #endregion
      31. }
      32. }
      33.  
      As you can see in the ProcessRequest method, the HTTP handler has access to all ASP.NET intrinsic objects passed to it in its parameter through the System.Web.HttpContext object. Implementing the ProcessRequest method is simply extracting the HttpResponse object from the context object and then sending some HTML out to the client. Similarly, IsReusable returns true to designate that this handler can be reused for processing the other HTTP requests.
      Let's compile it and place it in the bin directory of the webapp virtual directory.
      Step 2
      Register this handler by adding the following text in the web.config file:
      1. <httpHandlers>
      2. <add verb="*" path="*.15seconds" type="MyHandler.NewHandler,MyHandler"/>
      3. </httpHandlers>
      Step 3
      Since we are creating a handler for handling files of a new extension, we also need to tell IIS about this extension and map it to ASP.NET. If we don't perform this step and try to access the Hello.15seconds file, IIS will simply return the file rather than pass it to ASP.NET runtime. As a consequence, the HTTP handler will not be called.
      Launch the Internet Services Manager tool, right click on Default Web Site, select Properties, go to Home Directory tab and press Configuration button. This will popup Application Configuration dialog. Click Addbutton and fill the Executable field with the path to the aspnet_isapi.dll file and fill .15seconds in the Extensionfield. Leave the other fields as is; the dialog box should look as follows:

      Figure 2
      Close the Application Configuration and Default Web Site Properties dialog boxes by pressing the OKbutton.
      Now we are good to go. Launch Internet Explorer and go to the following url:
      http://localhost/webapp/hello.15seconds
      You should see the following page:

      Figure 3
      Session State in HTTP Handlers
      Maintaining session state is one of the most common tasks that Web applications perform. HTTP handlers also need to have access to the session state. But session state is not enabled by default for HTTP handlers. In order to read and/or write session data, HTTP handlers are required to implement one of the following interfaces:
      • IRequiresSessionState
      • IReadOnlySessionState.
      An HTTP handler should implement the IRequiresSessionState interface when it requires read-write access to the session data. If a handler only needs read access to session data, then it should only implement the IReadOnlySessionState interface.
      Both of these interfaces are just marker interfaces and do not contain any methods. So if we want to enable session state for our NewHandler handler, then declare the NewHandler class as followed:
      1. public class NewHandler : IHttpHandler, IRequiresSessionState
      2.  
      HTTP Modules
      HTTP modules are .NET components that implement the System.Web.IHttpModule interface. These components plug themselves into the ASP.NET request processing pipeline by registering themselves for certain events. Whenever those events occur, ASP.NET invokes the interested HTTP modules so that the modules can play with the request.
      An HTTP module is supposed to implement the following methods of the IHttpModule interface:
      Method NameDescription
      InitThis method allows an HTTP module to register its event handlers to the events in the HttpApplication object.
      DisposeThis method gives HTTP module an opportunity to perform any clean up before the object gets garbage collected.
      An HTTP module can register for the following events exposed by the System.Web.HttpApplication object.
      Event NameDescription
      AcquireRequestStateThis event is raised when ASP.NET runtime is ready to acquire the Session state of the current HTTP request.
      AuthenticateRequestThis event is raised when ASP.NET runtime is ready to authenticate the identity of the user.
      AuthorizeRequestThis event is raised when ASP.NET runtime is ready to authorize the user for the resources user is trying to access.
      BeginRequestThis event is raised when ASP.NET runtime receives a new HTTP request.
      DisposedThis event is raised when ASP.NET completes the processing of HTTP request.
      EndRequestThis event is raised just before sending the response content to the client.
      ErrorThis event is raised when an unhandled exception occurs during the processing of HTTP request.
      PostRequestHandlerExecuteThis event is raised just after HTTP handler finishes execution.
      PreRequestHandlerExecuteThis event is raised just before ASP.NET begins executing a handler for the HTTP request. After this event, ASP.NET will forward the request to the appropriate HTTP handler.
      PreSendRequestContentThis event is raised just before ASP.NET sends the response contents to the client. This event allows us to change the contents before it gets delivered to the client. We can use this event to add the contents, which are common in all pages, to the page output. For example, a common menu, header or footer.
      PreSendRequestHeadersThis event is raised just before ASP.NET sends the HTTP response headers to the client. This event allows us to change the headers before they get delivered to the client. We can use this event to add cookies and custom data into headers.
      ReleaseRequestStateThis event is raised after ASP.NET finishes executing all request handlers.
      ResolveRequestCacheThis event is raised to determine whether the request can be fulfilled by returning the contents from the Output Cache. This depends on how the Output Caching has been setup for your web application.
      UpdateRequestCacheThis event is raised when ASP.NET has completed processing the current HTTP request and the output contents are ready to be added to the Output Cache. This depends on how the Output Caching has been setup for your Web application.
      Apart from these events, there are four more events that we can use. We can hook up to these events by implementing the methods in the global.asax file of our Web application.
      These events are as follows:
      • Application_OnStart
        This event is raised when the very first request arrives to the Web application.
      • Application_OnEnd
        This event is raised just before the application is going to terminate.
      • Session_OnStart
        This event is raised for the very first request of the user's session.
      • Session_OnEnd
        This event is raised when the session is abandoned or expired.
      Registering HTTP Modules in Configuration Files
      Once an HTTP module is built and copied into the bin directory of our Web application or copied into the Global Assembly Cache, then we will register it in either the web.config or machine.config file.
      We can use <httpModules> and <add> nodes for adding HTTP modules to our Web applications. In fact the modules are listed by using <add> nodes in between <httpModules> and </httpModules> nodes.
      Since configuration settings are inheritable, the child directories inherit configuration settings of the parent directory. As a consequence, child directories might inherit some unwanted HTTP modules as part of the parent configuration; therefore, we need a way to remove those unwanted modules. We can use the <remove> node for this.
      If we want to remove all of the inherited HTTP modules from our application, we can use the <clear> node.
      The following is a generic example of adding an HTTP module:
      
      <httpModules>
       <add type="classname, assemblyname" name="modulename"  />
      
      <httpModules>
      
      
      The following is a generic example of removing an HTTP module from your application.
      
      <httpModules>
       <remove name="modulename"  />
      <httpModules>
      
      
      In the above XML,
      • The type attribute specifies the actual type of the HTTP module in the form of class and assembly name.
      • The name attribute specifies the friendly name for the module. This is the name that will be used by other applications for identifying the HTTP module.
      Use of HTTP Modules by the ASP.NET Runtime
      ASP.NET runtime uses HTTP modules for implementing some special features. The following snippet from the machine.config file shows the HTTP modules installed by the ASP.NET runtime.
      
      <httpModules>
       <add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
       <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
       <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="UrlAuthorization"
         type="System.Web.Security.UrlAuthorizationModule"/>
       <add name="FileAuthorization"
         type="System.Web.Security.FileAuthorizationModule"/>
      </httpModules>
      
      
      All of the above HTTP modules are used by ASP.NET to provide services like authentication and authorization, session management and output caching. Since these modules have been registered in machine.config file, these modules are automatically available to all of the Web applications.
      Implementing an HTTP Module for Providing Security Services
      Now we will implement an HTTP module that provides security services for our Web application. Our HTTP module will basically provide a custom authentication service. It will receive authentication credentials in HTTP request and will determine whether those credentials are valid. If yes, what roles are the user associated with? Through the User.Identity object, it will associate those roles that are accessible to our Web application pages to the user's identity.
      Following is the code of our HTTP module.
      
      using System;
      using System.Web;
      using System.Security.Principal;
      
      namespace SecurityModules
      {
       /// <summary>
       /// Summary description for Class1.
       /// </summary>
      
       public class CustomAuthenticationModule : IHttpModule
       {
        public CustomAuthenticationModule()
        {
        }
        public void Init(HttpApplication r_objApplication)
        {
         // Register our event handler with Application object.
         r_objApplication.AuthenticateRequest += 
                     new EventHandler(this.AuthenticateRequest) ;
        }
      
        public void Dispose()
        {
         // Left blank because we dont have to do anything.
        }
      
        private void AuthenticateRequest(object r_objSender,
                                         EventArgs r_objEventArgs)
        {
         // Authenticate user credentials, and find out user roles.
         1. HttpApplication objApp = (HttpApplication) r_objSender ;
         2. HttpContext objContext = (HttpContext) objApp.Context ;
         3. if ( (objApp.Request["userid"] == null) ||
         4.                     (objApp.Request["password"] == null) )
         5. {
         6.  objContext.Response.Write("<H1>Credentials not provided</H1>") ;
         7.  objContext.Response.End() ;
         8. }
      
         9. string userid = "" ;
         10. userid = objApp.Request["userid"].ToString() ;
         11. string password = "" ;
         12. password = objApp.Request["password"].ToString() ;
         
         13. string[] strRoles ;
         14. strRoles = AuthenticateAndGetRoles(userid, password) ;
         15. if ((strRoles == null) || (strRoles.GetLength(0) == 0))
         16. {
         17. objContext.Response.Write("<H1>We are sorry but we could not
             find this user id and password in our database</H1>") ;
         18. objApp.CompleteRequest() ;
         19. }
      
         20. GenericIdentity objIdentity = new GenericIdentity(userid,
                                                   "CustomAuthentication") ;
         21. objContext.User = new GenericPrincipal(objIdentity, strRoles) ;
        }
      
        private string[] AuthenticateAndGetRoles(string r_strUserID,
                                                       string r_strPassword)
        {
         string[] strRoles = null ;
         if ((r_strUserID.Equals("Steve")) &&
                                        (r_strPassword.Equals("15seconds")))
         {
          strRoles = new String[1] ;
          strRoles[0] = "Administrator" ;
         }
         else if ((r_strUserID.Equals("Mansoor")) &&
                                              (r_strPassword.Equals("mas")))
         {
           strRoles = new string[1] ;
           strRoles[0] = "User" ;    
          }
          return strRoles ;
         }
        }
      }
      
      Let's explore the code.
      We start with the Init function. This function plugs in our handler for the AuthenticateRequest event into the Application object's event handlers list. This will cause the Application object to call this method whenever the AuthenticationRequest event is raised.
      Once our HTTP module is initialized, its AuthenticateRequest method will be called for authenticating client requests. AuthenticateRequest method is the heart of the security/authentication mechanism. In that function:
      Line 1 and Line 2 extract the HttpApplication and HttpContext objects. Line 3 through Line 7 checks whether any of the userid or password is not provided to us. If this is the case, error is displayed and the request processing is terminated.
      Line 9 through Line 12 extract the user id and password from the HttpRequest object.
      Line 14 calls a helper function, named AuthenticateAndGetRoles. This function basically performs the authentication and determines the user role. This has been hard-coded and only two users are allowed, but we can generalize this method and add code for interacting with some user database to retrieve user roles.
      Line 16 through Line 19 checks whether the user has any role assigned to it. If this is not the case that means the credentials passed to us could not be verified; therefore, these credentials are not valid. So, an error message is sent to the client and the request is completed.
      Line 20 and Line 21 are very important because these lines actually inform the ASP.NET HTTP runtime about the identity of the logged-in user. Once these lines are successfully executed, our aspx pages will be able to access this information by using the User object.
      Now let's see this authentication mechanism in action. Currently we are only allowing the following users to log in to our system:
      • User id = Steve, Password = 15seconds, Role = Administrator
      • User id = Mansoor, Password = mas, Role = User
      Note that user id and password are case-sensitive.
      First try logging-in without providing credentials. Go to http://localhost/webapp2/index.aspx and you should see the following message.

      Figure 4
      Now try logging-in with the user id "Steve" and password "15seconds". Go to http://localhost/webapp2/index.aspx?userid=Steve&password=15seconds and you should see the following welcome message.

      Figure 5
      Now try to log-in with the user id "Mansoor" and password "15seconds". Go to http://localhost/webapp2/index.aspx?userid=Mansoor&password=mas and you should see the following welcome page.

      Figure 6
      Now try to log-in with the wrong combination of user id and password. Go to http://localhost/webapp2/index.aspx?userid=Mansoor&password=xyz and you should see the following error message.

      Figure 7
      This shows our security module in action. You can generalize this security module by using database-access code in the AuthenticateAndGetRoles method.
      For all of this to work, we have to perform some changes in our web.config file. First of all, since we are using our own custom authentication, we don't need any other authentication mechanism. To specify this, change the <authentication> node in web.config file of webapp2 to look like this:
      
      <authentication mode="None"/>
      
      Similarly, don't allow anonymous users to our Web site. Add the following to web.config file:
      
      <authorization>
       <deny users="?"/>
      </authorization>
      
      
      
      Users should at least have anonymous access to the file that they will use for providing credentials. Use the following configuration setting in the web.config file for specifying index.aspx as the only anonymously accessible file:
      
      <location path="index.aspx">
       <system.web>
        <authorization>
         <allow users="*"/>
        </authorization>
      
       </system.web>
      </location>
      
      
      Conclusion
      As you might have realized with HTTP handlers and modules, ASP.NET has put a lot of power in the hands of developers. Plug your own components into the ASP.NET request processing pipeline and enjoy the benefits.
      This article should at least get you started with these components. As an exercise, you might want to go and make this sample authentication module more flexible and tune it according to your needs.

    1, HTTPModule:
        It's just like a filter. The Modules are called before and after the handler executes.
        For example: BeginRequest, AuthenticationRequest event, EndRequest event etc. You may intercept , participate and modify each request.
        Modules implement the IHttpMudule interface located in the System.Web.System.
    2, HTTPHandler:
        You may think it as a  program.(or handler, or module), it execute some code when the user send some request. An .aspx page can be thought as a HTTPHandler too, which implements more functions.
    For may Information, Pls refer to:
    <div class=title>
    HTTP Handlers and HTTP Modules in ASP.NET
    </div>
    How To Create an ASP.NET HTTP Handler by Using Visual C# .NET
    <div class=majorTitle>ASP.NET  </div> <div class=title>Introduction to HTTP Handlers</div> <div class=title> </div> <div class=title>http://msdn2.microsoft.com/en-us/library/tfd6k449.aspx</div> <div class=title>How to: Create and Configure an HTTP Module</div> <div class=title> </div> <div class=title>http://windowssdk.msdn.microsoft.com/en-us/library/tkwek5a4.aspx</div> <div class=title> <div class=majorTitle>ASP.NET Configuration </div> <div class=title>Example Configuration Code for an HTTP Module</div> <div class=title> </div> <div class=title> </div></div>
  • An ASP.NET HTTP handler is the process (frequently referred to as the "endpoint") that runs in response to a request made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page through the page handler. You can create your own HTTP handlers that render custom output to the browser.
    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.
    Typical uses for custom HTTP handlers include the following:
    • RSS feeds   To create an RSS feed for a Web site, you can create a handler that emits RSS-formatted XML. You can then bind a file name extension such as .rss to the custom handler. When users send a request to your site that ends in .rss, ASP.NET calls your handler to process the request.
    • Image server   If you want a Web application to serve images in a variety of sizes, you can write a custom handler to resize images and then send them to the user as the handler's response.
    Typical uses for HTTP modules include the following:
    • Security   Because you can examine incoming requests, an HTTP module can perform custom authentication or other security checks before the requested page, XML Web service, or handler is called. In Internet Information Services (IIS) 7.0 running in Integrated mode, you can extend forms authentication to all content types in an application.
    • Statistics and logging   Because HTTP modules are called on every request, you can gather request statistics and log information in a centralized module, instead of in individual pages.
    • Custom headers or footers   Because you can modify the outgoing response, you can insert content such as custom header information into every page or XML Web service response.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.
      An ASP.NET HTTP handler is the process (frequently referred to as the "endpoint") that runs in response to a request made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page through the page handler. You can create your own HTTP handlers that render custom output to the browser.

After endless searching for answers to my handler setup questions, I finally decided to write an all-inclusive set of articles about how someone should go about this. If you find any errors or see room for improvement in any way, please let me know - I will make sure to note any contributions in the "Special Thanks" section. This will be my first contribution to this article-set.
Introduction
All requests to IIS are handled through Internet Server Application Programming Interface (ISAPI) extensions.ASP.NET has its own filter to ensure pages are processed appropriately. By default, the ASP.NET ISAPI filter (aspnet_isapi.dll) only handles ASPX, ASMX, and all other non-display file formats used by .NET and Visual Studio. However, this filter can be registered with other extensions in order to handle requests to those file types, too, but that will be covered later.
Every request flows through a number of HTTP modules, which cover various areas of the application (i.e. authentication and session intofmation). After passing through each module, the request is assigned to a single HTTP handler, which determines how the system will respond to the request. Upon completion of the request handler, the response flows back through the HTTP modules to the user.
HTTP Module
HTTP modules are executed before and after the handler and provide a method for interacting with the request. Custom modules must implement the System.Web.IHttpModule interface. Modules are typically synchronized with events of the System.Web.IHttpModule class (implemented within the Global.asax.cs or .vb file). The following consists of a list of events that should be considered when implementing your module:
  • BeginRequest
  • AuthenticateRequest
  • AuthorizeRequest
  • ResolveRequestCache
  • AcquireRequestState
  • PreRequestHandlerExecute
  • PostRequestHandlerExecute
  • ReleaseRequestState
  • UpdateRequestCache
  • EndRequest
  • PreSendRequestHeaders*
  • PreSendRequestContent*
  • Error*
The events identified by an asterisk (*) can occur at any time within the request; all others are listed in their calling order.
HTTP Handlers
HTTP handlers proces the request and are generally responsible for initiating necessary business logic tied to the request. Custom handlers must implement the System.Web.IHttpHandler interface. Additionally, a handler factory can be created which will analyze a request to determine what HTTP handler is appropriate. Custom handler factories implement the System.Web.IHttpHandlerFactory interface.
When to use Modules and Handlers
With all of the options available in ASP.NET, it is sometimes hard to determine what solution best fits your needs. Of course, it's always best to keep things simple; but, you still need to take evolutionary considerations and experience levels of current and future team members who have a potential of working on teh project into account. Both modules and handlers add a layer of indirection that can be daunting to beginners and/or programmers who are not used to implementing quality designs (read: design patterns).
First, consider what it is that you want to do within your module or handler. Some functions, such as authentication and intstrumentation can be added within modules. Modules should be considered only when there is a need for pass-through and/or intercepting interaction with the request. Alternatively, handlers should be put in place when there is a need to direct functional actions to one or more parts of an application. Probably the most noted use of HTTP handlers is to the FrontController pattern, which allows requests to be refactored and assigned to different components within your application without implementing such changes in every page.
Second, is it worth it? Most applications do not require this level of indirection, which can be hard to understand and/or implement when not documented properly. Some methods, such as the PageController pattern, allow for common functionality to be reused across multiple pages by including this logic in a base System.Web.UI.Pageobject, and inheriting from this for every web page. When reviewing the PageController implementation, you should know and understand the appropriate use of inheritence. Although certain things can be done this way (i.e. authorization and instrumentation), this is not always the correct means. You should fully understand the pros/cons of utilizing both modules and handlers before deciding on one implementation over the other.
With each of these considerations, and more, the decision to implement modules and/or handlers can be a daunting one. Such decisions should be led by an experienced .NET architect. In the absense of a skilled architect, you will be looking at a lot of leg-work to determine the best solution.
Conclusion
HTTP modules and handlers can be complex. Take the time to fully understand their pros/cons before implementing a solution. I recommend exploiting the experience of software architects whether in your organization or in the community. Whatever you choose, good luck on your ventures. I am finalizing my HTTP handler project, so I should be releasing an article with a sample implementation as well as any recommendations I may have for approaching the job within the next few weeks.
References
ASP.NET HTTP Modules and HTTP Handlers Overview
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q307985

Difference between HttpHandler and HttpModule

HttpHandler:

1.Meaning:

An ASP.NET HTTP handler is the process (frequently referred to as the "endpoint") that runs in response to a request made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page through the page handler. We can create our own HTTP handlers that render custom output to the browser.In order to create a Custom HTTP Handler,we need to Implement IHttpHandler interface(synchronous handler) or
Implement IHttpAsyncHandler(asynchronous handler).

2.When to use HTTP handlers:

RSS feeds: To create an RSS feed for a Web site, we can create a handler that emits RSS-formatted XML. We can then bind a file name extension such as .rss to the custom handler. When users send a request to your site that ends in .rss, ASP.NET calls our handler to process the request.
Image server: If we want a Web application to serve images in a variety of sizes, we can write a custom handler to resize images and then send them to the user as the handler’s response.

3.How to develop an ASP.NET handler:

All we need is implementing IHttpHandler interface

public class MyHandler :IHttpHandler
{
public bool IsReusable
{
get { return false; }
}

public void ProcessRequest(HttpContext context)
{

}
}

4.Number of HTTP handler called:

During the processing of an http request, only one HTTP handler will be called.

5.Processing Sequence:

In the asp.net request pipe line ,http handler comes after http Module and it is the end point objects in ASP.NET pipeline.

6.What it does actually?

HTTP Handler actually processes the request and produces the response

7.HTTP Handler implement following Methods and Properties:

Process Request: This method is called when processing asp.net requests. Here you can perform all the things related to processing request.
IsReusable: This property is to determine whether same instance of HTTP Handler can be used to fulfill another request of same type.

8. Configuring HTTP handler in web.config :
We can use <httpHandlers> and <add> nodes for adding HTTP
handlers to our Web applications. In fact the handlers are
listed with <add> nodes in between <httpHandlers> and
</httpHandlers> nodes.
Ex: <httpHandlers>
<add verb="supported http verbs" path="path"
type="namespace.classname, assemblyname" />
<httpHandlers>
(In this verb=GET/POST/HEAD path=path for
incoming HTTP requests type=…)

9.Summary:

If we need to create a request handler, for example we may want our own code to handle all .jpg image file requests like: http://mysite.com/filename.jpg, then we need to use HttpHandlers for this purpose.


HttpModule:
1. Meaning:

An HTTP module is an assembly that is called on every request that is made to our 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 examine incoming and outgoing requests and take action based on the request.

2.When to use HTTP modules:

Security: Because we can examine incoming requests, an HTTP module can perform custom authentication or other security checks before the requested page, XML Web service, or handler is called. In Internet Information Services (IIS) 7.0 running in Integrated mode, we can extend forms authentication to all content types in an application.
Statistics and logging: Because HTTP modules are called on every request, we can gather request statistics and log information in a centralized module, instead of in individual pages.
Custom headers or footers: Because we can modify the outgoing response, we can insert content such as custom header information into every page or XML Web service response.

3.How to develop a Http Module:

All we need is implementing System.Web.IHttpModule interface.

public class MyHttpModule : IHttpModule
{
public void Dispose()
{

}

public void Init(HttpApplication context)
{
//here we have to define handler for events such as BeginRequest ,PreRequestHandlerExecute ,EndRequest,AuthorizeRequest and ....

}

// you need to define event handlers here
}

4.Number of HTTP module called:

Whereas more than one HTTP modules may be called. 

5. Processing Sequence:

In the asp.net request pipe line, http Module comes first.

6.What it does actually?

HTTP module can work on request before and on the response after HTTP Handler 

7.Http Module implements following Methods and Properties:

InIt: This method is used for implementing events of HTTP Modules in HTTPApplication object.
Dispose: This method is used perform cleanup before Garbage Collector destroy everything.

8.Configuring HTTP Modules in web.config:
Ex: <system.web>
<httpModules>
<add name="MyModule"
type="MyModule.SyncModule, MyModule" />
</httpModules>
</system.web>
9.Summary:

If we want to modify a certain request, like we may want to perform some custom logic behind the scenes whenever user requests pages like mysite.com/default.aspx, we need to use HttpModules. We can create multiple HttpModules to filter any request.
ASP.NET HTTP Handlers are a new technique presented in ASP.NET that was not present in the "Classic" ASPHTTP Handlers are components that implement the System.Web.IHttpHandler interface. Unlike ASP.NET Pages, they have no HTML-markup file, no events and other supporting. All they have is a code-file (written in any .NET-compatible language) that writes some data to the server HTTP response. HTTP handlers are similar to ISAPI extensions.
An ASP.NET HTTP handler is basically a process that runs in response to a request made to an ASP.NET Web application. The most common handler is the ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page through the page handler.
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.
Unlike pages, that have ".aspx" file extension, ASP.NET handlers by default have ".ashx" file extension.
Handlers are considered to be more lightweight object than pages. That's why they are used to serve dynamically-generated images, on-the-fly generated PDF-files and similar content to the web browser.

External links[edit]