Hook up to arbitrary HttpModule event in global.asax

First of all, if you are already aware of the technique you can use to bind an event handler to the arbitrary event of the arbitrary HttpModule registered within your application using global.asax file, then, I am terribly sorry - there is most probably nothing new in this post for you (while still you may find subtleties you did not know previously).

Otherwise, if you are like me and from time to time you stumble upon the task when you want to handle some event of some HttpModule and can't easily find a way to do it, then read on.

So, you need to handle an event (let's name it MyEvent) of some HttpModule (let's name it MyModule). Let's also assume that the event takes event arguments instance of custom type MyEventArgs.

You may find that one of the solutions suggested for the task (for example in "Pro ASP.NET 3.5 in C# 2008" book from Apress) is to register event handler within an Init() method of another HttpModule:

public void Init(HttpApplication httpApp)
{
 MyModule module = httpApp.Modules["MyModule"];
 module.MyEvent += MyEventHandler;
}

But there is another approach I'd like to share with you.

Of course you already know that you may handle HttpApplication instance's events using global.asax file. For example you may use Application_Start method within the file to handle Start event of HttpApplication instance.

What you might not be aware of is that using the same syntax you may handle ANY event of ANY HttpModule registered for your application. In our case it is enough to write following code in global.asax to handle event named MyEvent of HttpModule named MyModule:

protected void MyModule_MyEvent(object sender, MyEventArgs e) {
 // handler implementation
}

There  are several subtleties to note:

  1. MyModule is not the name of the HttpModule class. It is the name under which the HttpModule is registered in configuration file (web.config);
  2. Name of the module is not case sensitive within the name of the method;
  3. Second part of the method name (name of the event - MyEvent) is not case sensitive either;
  4. You may, if you wish, add "on" prefix (also is not case sensitive) to event name within the method name.

Let me illustrate the three last statements with examples. All the following are perfectly valid declarations for such method:

protected void MyMODULE_MyEvent(object sender, MyEventArgs e) {  }

protected void MyModule_myEvent(object sender, MyEventArgs e) {  }

protected void MyModule_OnMyEvent(object sender, MyEventArgs e) {  }

protected void mymodule_onmyevent(object sender, MyEventArgs e) {  }

And the last piece of information I wanted to share is what actually makes this magic possible. All the related logic can be found within following methods: HttpApplicationFactory.ReflectOnMethodInfoIfItLooksLikeEventHandler and HttpApplication.HookupEventHandlersForApplicationAndModules. Names of the classes and methods are self-explanatory.

Hope this helps.

4 Comments

  • Good info, but would've been great if you had provided some solution where you applied this.

    Arun

  • Hi Arun,

    One of the cases when you may need to use this technique is to provide handlers for standard authentication modules like WindowsAuthenticationModule, FormsAuthenticationModule or DefaultAuthenticationModule. This way you do not need to write another HttpModule to assign IPrinciple instance to the HttpContext.User. You just need to attach to Authenticate event of one of these authentication modules. For example:
    // global.asax
    protected void FormsAuthentication_Authenticate(object seneder, FormsAuthenticationEventArgs e)
    {
    e.User = MyIPrincipal; // your custom IPrincipal instance
    }

    But of course, it is just one of potential cases when this technique may be useful.
    Hope this helps.

  • FANTASTIC! I've been googling for two days trying to find out why my custom event was not being recognised. Inspection of the HttpApplicationFactory.ReflectOnMethodInfoIfItLooksLikeEventHandler method using Reflector showed me where I was going wrong. It also allows me to add a few more subtleties to your list that are crucial if this autoevent wireup is to take place.

    5. The signature of the event delegate must be of the form

    void functionName(object s, MyArgs a)

    To be even clearer:
    - the event handler's return type must be void
    - there must be two parameters, exactly
    - the first parameter must be of type object
    - MyArgs must either be EventArgs or a descendant of.

    Excellent work! Thank you for the pointer to the function.

  • clarenceg,

    Thank you for your feedback and the additional information.

Comments have been disabled for this content.