ASP.NET developers typically handle a Page object’s Load event with a Page_Load event handler. In 1.x the designer generates code inside an InitializeComponent method to explicitly wire Page_Load to the Load event.
Lately, I’ve seen more than a handful of people dropping the Page_Load event handler in favor of overriding the Page OnLoad method. This appears to be happening more and more in 2.0, for a few reasons.
First, for C# developers using a separate CodeFile, it’s not immediately obvious how to add any Page event handler if the event is not already present. Unlike the VB editor, there are no drop down controls available to add an event, and intellisense offers no assistance. The method signature has to exactly match what ASP.NET will be looking for, because C# webforms use AutoEventWireup=”true”. Ironically, VB webforms use AutoEventWireup=”False” because the Handles keyword allows a VB developer to wire up an event in place.
Secondly, there is a small performance benefit in not creating a delegate (with reflection no less) and having the garbage collector clean up the same delegate afterwards.
I’ve been thinking about the OnLoad approach, and I even posted code in a recent entry using OnLoad instead of Page_Load. I’m not comfortable enough to make the switch, however. The purpose of OnLoad is to raise a Load event. Overriding a virtual method implies I want to change that behavior, which isn’t precisely true – I just want to setup the webform and get ready for databinding, etc. There is also a comfortable consistency in handling all Page and control events using event handlers of the form VariableName_EventName. Finally, if someone forgets to forward the OnLoad call to the base class, frameworks will break easily.
Opinions?
P.S. To add Page event handlers in C# code easily, use inline code instead of a separate code file. The ASPX editor provides the drop down controls to select Page events when in source view. Drag and drop, baby. It’s the future.
Comments
Perhaps even cleaner is to use a template method approach. Create a base class that inherits from Page. Then declare a method:
public virtual void PageOnBeforeLoad() {};
public virtual void PageOnAfterLoad() {};
Then implement OnLoad in the base class:
public override OnLoad()
{
PageOnBeforeLoad();
base.OnLoad();
PageOnAfterLoad();
}
Then your page inherits from this base page and you have the option to override whichever method you please, without adding the slight overhead of the event delegation that Page_Load incurs.
I don't like of the "Control_EventName" form. I believe that AutoEventWireup attribute is very powerful feature, but demands the creation delegate in C# (or Handles keyword in VB.NET). In the ASP.NET 2.0 some things are implicitly (or magic?) constructed.
Particularly I don't like Code Inline. Maybe because of the Code Behind elegance and my comfort.
Regards,
Corrections:
Using Visual Studio 2003 by default C# webforms has AutoEventWireup="flase"
Some of our pages don't even need the Load event (everything is initialized in OnInit), so having Page_Load only creates "visual pollution."
It's awkward that the page template overrides OnInit, but creates a delegate for Load. Feels inconsistent.
To add insult to injury, I think the delegate signature is ugly. Who ever uses the sender paramter?
Forgetting to call the base OnLoad or On[Whatever] could be a problem---you have a good point there, although you don't miss much by not calling base.OnLoad in your Page-derived class.
++ OnLoad lets you control the order things are done in.
-- OnLoad lets you mess up the order things are done in.
I'm not able to select the page events in a drop-down if I choose to "place code in seperate file". I could with VS2003, is this a bug or is it this way for a reason?
I think it's by design - I'm not sure. I noticed it in Beta 2.
the VS2003 help has a phrase "Note to inheritors: it's recommended that you override the base method rather than catch an event from the base class" or such in the help on every event. I've noticed it's no longer there in the VS2005 help.
Also, I've found a small issue with using OnLoad. If you're using "cookieless" sessions, the OnLoad overrides method causes a new session to get created and your state data gets lost. Session state seems correct with "cookied" session and overriding the OnLoad. Using Page_Load method with cookieless session works fine.
Otherwise, I don't care ...