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 will help the users to examine the use of HTTP Modules and their use in extending the pipeline. The HTTP Pipeline is a series of extensible objects that are initiated by the ASP.NET runtime in order to process a request. Http Handlers and Http Modules are .NET components that serve as the main points of extensibility in the pipeline.
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
.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.
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
Http modules are
filters that can pre and post-process requests as they pass through the
pipeline. As a matter of fact, many of the services provided by ASP.NET are
implemented as HTTP Modules. Examples are modules which are used to implement
ASP.NET security as well as ASP.NET session state.
At the most fundamental
level, ASP.NET HTTP Modules are classes which implement the
System.Web.IHttpModule interface, illustrated below:
public interface IHttpModule
{
void Dispose();
void Init(HttpApplication context);
}
{
void Dispose();
void Init(HttpApplication context);
}
In order to insure
that your HttpHandler is hooked up to the HTTP pipeline requires an entry in
the application's web config. or the machine.config file. The same holds true
for HTTP modules. When an HTTP Module is added to the pipeline, the ASP.NET
runtime will call the methods of the IHttpModule interface at the appropriate
times. When the module is first created by the runtime, the Init method is
called. As illustrated above, the parameter passed into the Init method allows
your code to tie into the HttpApplication object.
Below
is a detailed explanation of the events.
· 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”.
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="*.abcd," 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.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>
HTTP Module vs Global.asax
1. HTTP Module is pluggable component that’s why could
be use for other web applications as well as on other server or in same server
where as Global.asax couldn’t.
2.
According to life cycle of Request, Request passed through HTTP Module first
and then through Global.asax
3.
Following are list of events which are supported in Global.asax but
unfortunately not in HTTP Module.
1.
Application_OnStart
This event is raised when the very first request passed through the web application.
This event is raised when the very first request passed through the web application.
2.
Application_OnEnd
This event is raised just before the application is going to terminate.
This event is raised just before the application is going to terminate.
3.
Session_OnStart
This event is raised for the very first request of the user's session.
This event is raised for the very first request of the user's session.
4. Session_OnEnd
This event is raised when the session is abandoned or expired.
This event is raised when the session is abandoned or expired.
No comments:
Post a Comment