多个Page_Load方法,被称为?

时间:2013-04-05 09:09:45

标签: asp.net pageload

在现有的ASP.NET应用程序中,我有一个包含Page_Load方法的基类:

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

我有一个继承自这个基类的实际页面。但是,它不会覆盖现有的Page_Load方法,但会声明一个新方法:

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

编译器向我发出警告,实际页面中的Page_Load方法隐藏了现有的Page_Load方法。实际上,有两种单独的Page_Load方法,因为旧的方法没有被覆盖,而是被隐藏。

现在我的问题是,ASP.NET架构在这种情况下的生命周期中做了什么?哪一个被叫?或者他们都被称为?

注意:我知道这是糟糕的设计,我不确定原作者的想法,我只是想了解发生了什么以及这将如何影响系统的逻辑。

2 个答案:

答案 0 :(得分:1)

经过一番挖掘后,我发现了正在发生的事情。

简短回答:只调用最顶层的方法!

起初,我在评论中提出了一些像MelanciaUK建议的断点。这表明我只调用了最顶层的方法。

深入挖掘,我看了一下volpav建议的内容。确实AutoEventWireup设置为true,这会自动将方法挂钩到事件处理程序(因为这确实不是手动完成的)。但是,与他声称的不同,只有顶级Page_Load方法被调用。

对这种类型的反思给了我一些线索:

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);

pageloads值最终包含两个结果:两个Page_Load方法,一个声明类型为ActualPage,另一个声明类型为PageBaseClass

虽然这会导致第二次调用出现问题,因为有两个结果,我预计会抛出AmbiguousMatchException。但事实并非如此。它包含MethodInfo中方法的ActualPage

深入挖掘,我偶然发现了K. Scott Allen的一篇文章:Inside AutoEventWireup http://odetocode.com/blogs/scott/archive/2006/02/16/inside-autoeventwireup.aspx

根据他的文章,接线事件正在发生如下:

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

我自己执行此操作,发现此调用会创建一个指向Page_Load的{​​{1}}方法的委托,与ActualPage调用返回该方法的方式相同。

因此,如果事件方法自动连接,它似乎不会连接任何被隐藏的方法。

答案 1 :(得分:0)

两个方法中的代码都将被调用,因为它们本质上是一个事件处理程序(一个由基类附加,另一个由您的“ActualPage”类附加)。这是因为“AutoEventWireup”属性设置为“true”(它在标记中默认设置)。

关于“AutoEventWireup”的相关问题:What does AutoEventWireUp page property mean?

<强>更新

原来我说错了,说两个方法都会被调用,事实上,只有在“ActualPage”上声明的方法被调用。请参阅Rene的答案。