此实现方法一开始就调用 FrameworkInitialize 方法,以此建立页面的控件树。此方法是 TemplateControl 类(Page 类本身就是从该类派生出来的)的一个受保护的虚拟成员。任何针对 .aspx 资源而动态生成的处理程序都重写 FrameworkInitialize。在此方法中,该页面的完整控件树得以构建。
接下来,ProcessRequest 使该页面经历若干阶段:初始化,加载视图状态信息和回发数据,加载页面的用户代码并执行回发服务器端事件。随后,该页面进入呈现模式:收集更新后的视图状态;生成 HTML 代码然后将其发送到输出控制台。最后,卸载页面,并认为已完成对该请求的处理。
在各个阶段中,页面都会激发一些 Web 控件和用户定义的代码所能截获并处理的事件。其中的一些事件是嵌入式控件专用的,因而并不能在 .aspx 代码级进行处理。
如果页面想要处理某个事件,它应该显式地注册相应的处理程序。然而,为了向后兼容早期的 Visual Basic 编程风格,ASP.NET 也支持一种隐式的事件挂起形式。在默认情况下,页面将尝试把特定的方法名与事件匹配起来;如果找到匹配的方法,就认为该方法是该事件的处理程序。ASP.NET 提供了六个方法名的特定识别。它们是 Page_Init、Page_Load、Page_DataBind、Page_PreRender 和 Page_Unload。这些方法被当作是 Page 类所提供的相应事件的处理程序。HTTP 运行时将自动把这些方法与页面事件绑定起来,这样一来,开发人员就不必编写所需的粘接代码。例如,名为 Page_Load 的方法与页面的 Load 事件绑定,就像已编写以下代码一样。
this.Load += new EventHandler(this.Page_Load);
这种自动识别特殊名称的功能由 @Page 指令的 AutoEventWireup 属性控制。如果将该属性设置为 false,则任何想要处理某个事件的应用程序都需显式地连接到该页面事件。如果页面不使用自动事件关联功能,就不必进行额外的操作以匹配各名称和事件,从而其性能也稍有提升。应该注意的是,所有的 Microsoft Visual Studio.NET 项目在创建时都禁用了 AutoEventWireup 属性。然而,此属性的默认设置为 true,意味着诸如 Page_Load 等方法会被识别并被绑定到相关的事件。
页面的执行过程包括下面表格中所列的一系列阶段,并以具有一些应用程序级事件和/或受保护且可重写的方法为特征。
表格 1. ASP.NET 页面生存周期中的关键事件
阶段 页面事件 可重写方法
页面初始化
Init
加载视图状态
LoadViewState
处理回发数据
实现 IPostBackDataHandler 接口的任何控件中的 LoadPostData 方法
加载页面
Load
回发更改通知
实现 IPostBackDataHandler 接口的任何控件中的 RaisePostDataChangedEvent 方法
处理回发事件
控件所定义的任何回发事件
实现了 IPostBackEventHandler 接口的任何控件的 RaisePostBackEvent 方法
页面呈现前阶段
PreRender
保存视图状态
SaveViewState
呈现页面
Render
卸载页面
Unload
在页面级上,以上所列的某些阶段是不可见的,并仅影响服务器控件编写者和那些凑巧要创建从 Page 派生的类的开发人员。页面向外界发送的活动信号仅包括 Init、Load、PreRender、Unload 以及嵌入式控件所定义的所有回发事件。