Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs
Contact   •   Articles   •   Products   •   Support   •   Search
Ad-free experience sponsored by:
ASPOSE - the market leader of .NET and Java APIs for file formats – natively work with DOCX, XLSX, PPT, PDF, images and more

Dynamically hooking up HttpModules


:P
On this page:

Ran into an interesting question on the ASP.NET newsgroup today regarding a problem I've run into a few times myself. The issue revolves around virtual directory folder inheritance and web.config settings getting inherited from a root Web site.

Anyway - one issue that has come up a few times is that the root site defines an HTTP module. The child virtual (an off the root virtual directory) when created by default inherits that module entry in web.config and usually fails because the module isn't available. Now it's easy to use a remove entry in your virtuals:

<remove name="TopLevelModule">

and that can usually take care of it. However, if you have many sub-virtuals you need to touch this can get tedious.

So rather than fixing the Web.config in each subapplication I've removed the module definition in web.config and instead load the module via code. HttpModules hook up to the HttpApplication object of an ASP.NET application which is represented by your global.asax file in a Web project. HttpModules hook up to the events of this HttpApplication object, and since all a module really does is attach to the appropriate event handler in its Init() method there's no reason that you can't do this in code as well.

There's one little gotcha though: It has to be done at just the right time in the HttpApplication life cycle which is when the HttpApplication object initializes (multiple times, once for each instance of HttpApplication). The only method where this works correct is HttpApplication Init().

To hook up a module via code you can run code like the following instead of the HttpModule definition in web.config:

public class Global : System.Web.HttpApplication
{
    public static xrnsToashxMappingModule Module = new xrnsToashxMappingModule();
 
    public override void Init()
    {
        base.Init();
        Module.Init(this);
    }
}

All you do is override the HttpApplication's Init() method and then access the static instance's Init method. Init() of the module hooks up the event and off you go.

Note the use of HttpApplication Init; you might be tempted to use Application_Start, but that event is more like a static constructor that fires only once per Web application. Init() fires everytime a new application instance is initialized. Remember there are multiple HttpApplication instances executing side by side to handle simultaneous requests and each instance initializes separately.

Using web.config is the preferred way of hooking up handles usually though for sure. But there are situations where you might not want to allow the module hookup to be dynamic. For example, if you have an application where the module is crucial to operation, performs some security feature, or version check, you might not want to allow removal of the module - this way it's a lot more difficult to disconnect the module. If you have a packaged application it can also be nice to have the set up hard coded in this fashion - one less thing to screw up during installation or when users start poking around in configuration files <s>.

Posted in ASP.NET  IIS  

The Voices of Reason


 

Kevin Dente
April 06, 2007

# re: Dynamically hooking up HttpModules

Another approach is to use <location> sections in the root web site to remove the handler on the sub-webs. Still requires listing out each sub-web, but at least you only need to muck with one web.config - the root one. Of course, the more sub-webs you have, the easier your approach is.

Atif Aziz
April 09, 2007

# re: Dynamically hooking up HttpModules

There is just one shortcoming with this (programmatic) way of hooking up a module and that is that the module does not show up in the HttpApplication.Modules collection. Unfortunately, there is also no programmatic way to get it registered in there at run-time since the collection is read-only. This may only be a limiting factor if some component along or adjacent to the HTTP pipeline is depending on the presence of the module in the collection in order to reach it (a trick that I often tend to rely on). Other than that, the tip is interesting.

# DotNetSlackers: Dynamically hooking up HttpModules


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2019