Monday, August 2, 2010

Page_Load and OnLoad

Today I relearned an important lesson on the Page_Load and OnLoad event handlers for ASP.Net user controls. We cannot assume that they are one and the same in the page lifecycle. By default Visual Studio will create an event handler for Page_Load when you doubleclick on the designer panel for a user control.



This default behavior of Visual Studio set up a disaster in conjunction with my SharePoint development framework.

In my framework I've created a Framework.Base.BaseUserControl class that inherits from the System.Web.UI.UserControl class. The purpose of this BaseUserControl class is to serve as an ancestor class for all my user controls that get deployed with SharePoint solutions. In addition, the web part wrapper class (i.e. Framework.Base.BaseWebPart) assumes that the wrapped user control descends from this class.

Here's the OnLoad event handler in BaseUserControl.

protected override void OnLoad(EventArgs e)
{
this.MyBaseControlLoadLogic();
base.OnLoad(e);
}

Here's the result in Visual Studio for my user control.


protected override void Page_Load(EventArgs e)
{
base.OnLoad(e);
this.MyControlLoadLogic();
}


Everything compiles. But then all I got was a blank screen. I did some debugging and then discovered my mistake. The base.OnLoad(e) call im my Page_Load was causing a stack overflow that crashed my development web server. All I had to do was rename Page_Load as OnLoad.


protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.MyControlLoadLogic();
}

It worked :)

1 comment:

  1. Subtle difference between OnLoad and Page_Load: OnLoad is the Page's lifecycle method that *fires* the Load event; Page_Load is an event-handler method that *responds* to the Load event. Understand this difference may clarify the cause of your stack overflow...

    1. The current request reaches the lifecycle's Load phase, and the framework calls your page's OnLoad method.
    2. Your page's OnLoad method calls the base Page.OnLoad method.
    3. The Page.OnLoad method fires the Page.Load event.
    4. Your page's Page_Load method responds to the Page.Load event.
    5. Your page's Page_Load method calls the base Page.OnLoad method.
    6. Go to step #3 and repeat until the call-stack overloads.

    Basically, use one or the other of these two methods (OnLoad performs slightly better, as it doesn't need to create a delegate and wire-up to an event), but whichever you use, make sure that OnLoad calls base.OnLoad, but Page_Load doesn't.

    ReplyDelete