Browse DevX
Sign up for e-mail newsletters from DevX


Implementing an IIS Application Filter Using .NET HttpModules and Response Filtering

In his previous article author Joseph Geretz demonstrated the use of HttpHandlers for processing Web requests. In this article, he introduces HttpModules, which are a complementary mechanism for processing Web requests. He concentrates on the critical differences in the processing model implemented by HttpHandlers versus that implemented by HttpModules, and presents specific coding samples as necessary in order to illustrate various points.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

n this article, I will concentrate on the critical differences in the processing model implemented by HttpHandlers versus that implemented by HttpModules. I'll be presenting specific coding samples as necessary in order in order to illustrate various points, but I won't be presenting a comprehensive sample of my own implementation.  A wealth of information and code samples are available to demonstrate how to establish an HttpModule to participate in your application’s web requests and I’ll present these links toward the end of the article. In the meantime, It's my hope that this article will complement the existing samples and documentation and assist you with the development of your own IIS Application filtering solution.
If you’ve worked with ISAPI filters under IIS4, the HttpModule processing model is probably nothing new to you. However ISAPI filtering under IIS4 was relatively out-of-bounds for VB developers and therefore the fundamental processing model may be less than intuitive to many VB developers.

HttpHandler—the Target for your Request
The HttpHandler model is relatively easy to understand. An HttpHandler is the target of a web request. In fact, a WebForm (.aspx) page derives from System.Web.UI.Page which implements the HttpHandler interface. Check it out in the object browser.

So as far as the processing model is concerned, writing your own HttpHandler is no different than writing a WebForm page or any other .aspx (or .asp) script. As with these scripts, the context of each web request is made available to the HttpHandler on a request-by-request basis. This context will include the global Server and Application objects as well as the Request, Response and Session objects which are relevant to the current request.

An HttpHandler is created specifically (or retrieved from the pool) for each request and is dedicated exclusively to that request for the remainder of its lifetime (or until it is released back to the pool). The active lifetime for each particular request begins when control enters ProcessRequest, and extends until control exits ProcessRequest. During this time, request specific data may be freely accumulated and cached globally since the entire scope of the active lifetime is dedicated to a specific request.

Note the IsReusable property defined in the IHttpHandler interface. If this is returned as true, then the HttpHandler will not be destroyed when control exits ProcessRequest. Rather, it will be released to the pool for use by a future requestor. Naturally, this means that request specific data must be de-initialized at the end of a request, or reinitialized at the beginning of a request. (Cautious developers may elect to initialize at both points.) This consideration is standard to object pooling in general and is not specific to HttpHandlers.

In my previous article, I described how I used an HttpHandler in order to implement a centralized request controller for my .NET web application. See that article for more details, but the basic strategy is to map all requests to a particular HttpHandler. That HttpHandler uses information coming in from the browser (e.g. QueryString, Cookie) in order to create and call the relevant handler class. The benefit of this model is that common pre-processing and post-processing can be centralized to the HttpHandler application controller. This guarantees that the relevant pre-processing and post-processing must be called for every request. It also means that when either of these request stages need to be modified, the change can be effected to a central location which will immediately impact all requests across the entire application.

The HttpHandler approach is a robust model for implementing a web application where request handlers are implemented as compiled classes which implement a common interface. As mentioned earlier, the HttpHandler instantiates the correct class for the current request and calls the defined interface method. The HttpHandler approach is less helpful though, if we’d like to take advantage of the RAD features offered by Visual Studio .NET and WebForms for rapid web application development.

As HttpHandlers, WebForms are designed to be invoked directly as the target of a browser request. However, using the centralized HttpHandler as an application controller means that all requests are mapped to that particular WebHandler. At this point, the application controller WebHandler (and not the WebForm script) becomes the target of the HTTP request. This becomes a significant barrier to WebForms style development.

I recently worked on a project where the rules changed midway through development. Initially, the developers who had come from a VB6/ASP background were quite amenable to the prospects of implementing the application request handlers as compiled classes. However, after seeing the brand new capabilities of .NET WebForms they decided that they just could not commit to a long-term restriction against the use of WebForms to develop application request handlers. Since WebForm facilities are based on the fundamentals of HTTP (query parameters, cookies and form fields) it is certainly possible, using the System.NET classes, to write code to issue a secondary request to, and to receive the response from, the .NET WebForm for those requests which are implemented as WebForms. Ultimately though, this would be a lot of work and tantamount to rewriting the web server! Fortunately, there is a counterpart mechanism, the HttpModule which allows us to impose centralized application-wide request processing without interfering with the target of the request emanating from the browser.

Before moving on to the HttpModule, I’d like to just re-emphasize the limitation presented by HttpHandler. Since the HttpHandler becomes the target of the request, it is difficult to engineer the application controller as an HttpHandler in an environment where the application request handlers are themselves implemented as HttpHandlers (as is the case with WebForms). This is not a flaw in the HttpHandler implementation; On the contrary, the HttpHandler is specifically designed to fulfill  the role of a request handler, rather than an application controller. In order to implement an application controller which can filter every application request, without disturbing the target HttpHandler for that request, we need to take a look at the HttpModule.

Thanks for your registration, follow us on our social networks to keep up-to-date