René Wolferink
René Wolferink

Reputation: 3548

Multiple Page_Load methods, which is called?

In an existing ASP.NET application, I have a base class containing a Page_Load method:

public class PageBaseClass : System.Web.UI.Page {
    protected virtual void Page_Load(object sender, EventArgs e) {
        // do stuff...
    }
}

I have an actual page which inherits from this base class. However, it doesn't override the existing Page_Load method, but declares a new one like this:

public class ActualPage : PageBaseClass {
    protected void Page_Load(object sender, EventArgs e) {
        // do other stuff...
    }
}

The compiler gives me a warning that the Page_Load method in the actual page is hiding the existing Page_Load method. So effectively, there are two seperate Page_Load methods, since the old one wasn't overridden, but hidden.

Now my question is, what does the ASP.NET architecture do in it's lifecycle in such a situation? Which one is being called? Or are they both being called?

Note: I know this is bad design, I'm not sure what the original author had in mind, I'm just trying to understand what's happening and how this will affect the logic of the system.

Upvotes: 1

Views: 544

Answers (2)

volpav
volpav

Reputation: 5128

The code in both methods will be called since these are essentially an event handlers (one which is attached by the base class, another one - by your "ActualPage" class). This is due to "AutoEventWireup" property set to "true" (it's set by default in your markup).

Related question on "AutoEventWireup": What does AutoEventWireUp page property mean?

UPDATE

Turned out I was wrong stating that both methods will be called and in fact, only the one declared on the "ActualPage" gets called. See Rene's answer below.

Upvotes: 0

René Wolferink
René Wolferink

Reputation: 3548

After some digging around, I've found out what's happening.

Short answer: only the top-most method is called!

At first I put down some breakpoints like MelanciaUK suggested in a comment. This showed me that only the top-most method was being called.

Digging deeper, I looked at what volpav suggested. It was true that AutoEventWireup was set to true, which was automatically hooking up the method to the event handler (since this indeed wasn't done manually). However, unlike he claimed, only the top Page_Load method was being called.

Reflecting over the type gave me a bit of a clue what was going on:

var pageloads = this.GetType().GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).Where(m => m.Name == "Page_Load");
var pageload = this.GetType().GetMethod("Page_Load", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

The pageloads value ended up containing two results: the two Page_Load methods, one with declaring type ActualPage and one with declaring type PageBaseClass.

I though that would cause problems for the second call, since having two results, I expected it to throw an AmbiguousMatchException. However, it did not. It contained the MethodInfo for the method in the ActualPage.

Digging deeper, I stumbled upon an article by K. Scott Allen: Inside AutoEventWireup http://odetocode.com/blogs/scott/archive/2006/02/16/inside-autoeventwireup.aspx

According to his article, wiring up events is happening as follows:

Delegate.CreateDelegate(typeof(EventHandler), this, "Page_Load", true, false);

Executing this myself, I found that this call creates a delegate pointing at the Page_Load method for the ActualPage, the same way the GetMethod call returned that method.

So it seems that in case an event-method is being wired up automatically, it will not wire up any methods that are being hidden.

Upvotes: 1

Related Questions