Skip navigation.
Even MSDN documentation is contradictory on this. For example, which is a correct handler for the Session.Start event? Session_Start or Session_OnStart? Documentation lists both in different places, and when you look it up newsgroups, you’ll read some pretty opinionated arguments about each.
Session.Start
Session_Start
Session_OnStart
For example, MSDN states:
You can use the Global.asax file to synchronize any event that is exposed by the HttpApplication base class. To do this, you must use the following naming pattern to author methods: Application_EventName(AppropriateEventArgumentSignature)
You can use the Global.asax file to synchronize any event that is exposed by the HttpApplication base class. To do this, you must use the following naming pattern to author methods:
Application_EventName(AppropriateEventArgumentSignature)
According to Framework Design Guidelines, section 5.4.1, Custom event handler design, an “appropriate event argument signature” is one with a return type of void; object as the type of the first parameter of the event handler, and called sender; System.EventArgs or its subclass as the type of the second parameter of the event handler, called e.
object
System.EventArgs
Nevertheless, you see the following code snippet time and time again:
void Session_OnStart() { // Session start-up code goes here. } void Session_OnEnd() { // Session clean-up code goes here. }
First, what happened to an appropriate signature? Second, the Session_End event is so flaky that you shouldn’t bank on it.
Session_End
Here’s another quote from Handling Public Events:
In any of these classes, look for the public events they define. You can hook them in Global.asax using the syntax ModuleName_OnEventName. For example, the Start event of the SessionStateModule module is declared protected void Session_Start(Object sender, EventArgs e) in Global.asax. You can use the syntax Session_OnStart in a <script runat=server> block in an ASP.NET application file to define an event handler for the Start event of the SessionStateModule.
Start
protected void Session_Start(Object sender, EventArgs e)
<script runat=server>
SessionStateModule
So do you need that On prefix or not? And should handlers be private, protected or public? No wonder there’s so much confusion over this.
How about a quiz? What if you define the following methods in global.asax (yes, all of them):
Having these five event handlers, which one(s) will be called? Place your bets.
It turns out all of them, except the last one, will be called, and in the same order as listed! Not that anyone would want to declare more than one, but it demonstrates that the On prefix does not matter. Neither does it the access modifier—private, protected or public—matter. As long as the handler has no arguments, or has two arguments that resemble a correct signature, it will be called.
I got curious why this was taking place and started digging with Reflector. Eventually, I found a method, HookupEventHandlersForAppplicationAndModules, inside the HttpApplication class. I believe this is where event handlers of modules are magically wired.
HookupEventHandlersForAppplicationAndModules
HttpApplication
This method goes through a list of methods that look like event handlers, extracts the part before the underscore (e.g. “Session” in Session_OnStart), and looks up an HttpModule with this name. It then extracts the part after the underscore (taking into account the optional On prefix), and then creates a delegate with the extracted name. Next, the method tries to add this delegate to the right event in the identified module. If an event handler had no parameters, a special ArglessEventHandlerProxy comes to the rescue.
ArglessEventHandlerProxy
The only missing bit is which methods in global.asax look like event handlers. You can see the algorithm in the ReflectOnMethodInfoIfItLooksLikeEventHandler method of HttpApplicationFactory. In a nutshell, this method checks if the method has a return type of void; and if the first argument to a method is of type object and the second—of type EventArgs or a derivative thereof. If the signature is satisfactory, the method is passed on as a possible event handler. A special case is a method without parameters—it’s treated as a potential event handler as well.
ReflectOnMethodInfoIfItLooksLikeEventHandler
HttpApplicationFactory
void
EventArgs
I hope at this point it is clear why all variations of Session.Start event handlers in global.asax, except the last one listed, were called. I still don’t understand the reason for all this late binding and the need to drag this file around. At least this article should settle disputes about the “proper” naming of event handlers within global.asax.
Liked it? Hated it? Discuss this article
My designer and developer OPML feed subscriptions are available for grabs.