ASP.NET页⾯事件执⾏过程(完整版)
ASP.NET 母版页和内容页中的事件
母版页和内容页都可以包含控件的事件处理程序。对于控件⽽⾔,事件是在本地处理的,即内容页中的控件在内容页中引发事件,母版页中的控件在母版页中引发事件。控件事件不会从内容页发送到母版页。同样,也不能在内容页中处理来⾃母版页控件的事件。
在某些情况下,内容页和母版页中会引发相同的事件。例如,两者都引发和事件。引发事件的⼀般规则是初始化事件从最⾥⾯的控件向最外⾯的控件引发,所有其他事件则从最外⾯的控件向最⾥⾯的控件引发。请记住,母版页会合并到内容页中并被视为内容页中的⼀个控件,这⼀点⼗分有⽤。
下⾯是母版页与内容页合并后事件的发⽣顺序:
1. 母版页控件 Init 事件。
2. 内容控件 Init 事件。
3. 母版页 Init 事件。
4. 内容页 Init 事件。
5. 内容页 Load 事件。
6. 母版页 Load 事件。
7. 内容控件 Load 事件。
8. 内容页 PreRender 事件。
9. 母版页 PreRender 事件。
10. 母版页控件 PreRender 事件。
11. 内容控件 PreRender 事件。
母版页和内容页中的事件顺序对于页⾯开发⼈员并不重要。但是,如果您创建的事件处理程序取决于某些事件的可⽤性,那么您将发现,了解母版页和内容页中的事件顺序很有帮助。
Page 执⾏中将按照如下顺序激活事件:
Page.PreInit
Page.Init
Page.InitComplite
Page.PreLoad
Page.Load
Page.LoadComplete
Page.PreRender
Page.PreRenderComplete
如果页⾯从另⼀个页⾯继承,如BasePage:System.Web.UI.Page,在BasePage中做了⼀些扩展,如权限检查,⽽其他页⾯从BasePage继承,则BasePage和最终Page的事件激活顺序是:
UI.PreInit
Page.PreInit
UI.Init
Page.Init
UI.InitComplite
Page.InitComplite
UI.PreLoad
Page.PreLoad
UI.Load
Page.Load
UI.LoadComplete
Page.LoadComplete
UI.PreRender
Page.PreRender
UI.PreRenderComplete
Page.PreRenderComplete
如果使⽤了MasterPage,则MasterPage中的事件和ContentPage中的事件按照下⾯顺序激活:
ContentPage.PreInit
Master.Init
ContentPage.Init
ContentPage.InitComplite
ContentPage.PreLoad
ContentPage.Load
Master.Load
ContentPage.LoadComplete
ContentPage.PreRender
更进⼀步,如果ContentPage继承BasePage,那么,各事件的执⾏顺序将变成:
UI.PreInit
ContentPage.PreInit
Master.Init
UI.Init
ContentPage.Init
UI.InitComplite
ContentPage.InitComplite
UI.PreLoad
ContentPage.PreLoad
UI.Load
ContentPage.Load
Master.Load
UI.LoadComplete
ContentPage.LoadComplete
UI.PreRender
ContentPage.PreRender
Master.PreRender
UI.PreRenderComplete
ContentPage.PreRenderComplete
浏览下来发现并不是我现在所学的asp 1.1,估计应该是asp 2.0,
不过也没有关系,这让我知道了他们有继承时加载的顺序。
即:先加载继承页的,再加载⾃⼰的,如果继承页有继承则先加载继承页的继承。
其实是个很简单的内容。顺便写下Page事件(不知道1.1是不是就这些)
事件处理器名称发⽣时间
在Web窗体的视图状态加载服务器控件并对其初始化。
Page_Init
这是web窗体⽣命周期的第⼀步
在Page对象上载⼊服务器控件。由于此时视图状态信息是可以使⽤的,
Page_Load
因此载这⾥可以⽤代码来改变空间的设置或者载页⾯上显⽰⽂本。
Page_PreRender应⽤程序将要呈现Page对象
Page_Unload页⾯从内存中卸载
Page_Error发⽣未处理的异常
Page_AbortTransaction事务处理被终⽌
Page_CommitTransaction事务处理被接受
Page_DataBinding把页⾯上的服务器空间和数据源绑定载⼀起
Page_Disposed Page对象从内存中释放掉。这是Page对象⽣命周期中的最后⼀个事件
Init,Load,PreRender事件执⾏顺序:
1)控件的Init事件
2)控件所在页⾯的Init事件
3)控件所在页⾯的Load事件
4)控件的Load事件
5)控件所在页⾯的PreRender事件
6)控件的PreRender事件
规律:
1)Init事件从最⾥⾯的控件(包括⽤户控件及普通控件)向最外⾯的控件(页⾯)引发,Load及PreRender等其他事件从最外⾯的控件向最⾥⾯的控件引发;
2)控件之间相同事件的执⾏顺序依控件在页⾯的位置按从左到右,从上到下的先后顺序执⾏。
注意:
1)切记⽤户控件也被视为页⾯中的⼀个控件;
2)把⽤户控件作为单独的⼀个特殊页⾯来看,它本⾝及其所包含的控件同样遵守相同的规律;
3)有时在客户端程序(如javascript)中会⽤到客户端body对像的onload事件,注意这个客户端事件是最后执⾏,即在服务器端所有事件执⾏完后才执⾏。
测试环境:
Windows2000 Pro+IIS5.0+Dotnet Framework1.1
===================================================================================
转载⼀篇关于页⾯对象模型的⽂章,说得⽐较详细,有助理解。没事的时候就多看两遍,慢慢体会:)。
ASP.NET 页⾯对象模型
Dino Esposito
2003 年 8 ⽉ 
适⽤于:
Microsoft® ASP.NET
摘要:了解为 ASP.NET Web 页⾯建⽴的事件模型,以及 Web 页⾯转变为 HTML 过程中的各个阶段。ASP.NET HTTP 运⾏时负责管理对象管道,这些对象⾸先将请求的 URL 转换成 Page 类的具体实例,然后再将这些实例转换成纯 HTML ⽂本。本⽂将探讨那些作为页⾯⽣命周期标志的事件,以及控件和页⾯编写者如何⼲预并改变标准⾏为。(本⽂包含⼀些指向英⽂站点的链接。)
⽬录
简介
真正的 Page 类
页⾯的⽣命周期
执⾏的各个阶段
⼩结
简介
对由 Microsoft® Internet 信息服务 (IIS) 处理的 Microsoft® ASP.NET 页⾯的每个请求都会被移交到 ASP.NET HTTP 管道。HTTP 管道由⼀系列托管对象组成,这些托管对象按顺序处理请求,并将 URL 转换为纯 HTML ⽂本。HTTP 管道的⼊⼝是 HttpRuntime类。ASP.NET 结构为辅助进程中的每个 AppDomain 创建⼀个此类的实例。(请注意,辅助进程为每个当前正在运⾏的 ASP.NET 应⽤程序维护⼀个特定的AppDomain。)
HttpRuntime 类从内部池中获取 HttpApplication 对象,并安排此对象来处理请求。HTTP 应⽤程序管理器完成的主要任务就是到将真正处理请求的类。当请求 .aspx 资源时,处理程序就是页⾯处理程
序,即从 Page 继承的类的实例。资源类型和处理程序类型之间的关联关系存储在应⽤程序的配置⽂件中。更确切地说,默认的映射集是在 fig ⽂件的 <httpHandlers>部分定义的。但是,应⽤程序可以在本地的 fig ⽂件中⾃定义⾃⼰的 HTTP 处理程序列表。以下这⼀⾏代码就是⽤来为 .aspx 资源定义 HTTP 处理程序的。
<add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>
扩展名可以与处理程序类相关联,并且更多是与处理程序⼯⼚类相关联。在所有情况下,负责处理请求的 HttpApplication 对象都会获得⼀个实现 IHttpHandler 接⼝的对象。如果根据 HTTP 处理程序来解析关联的资源/类,则返回的类将直接实现接⼝。如果资源被绑定到处理程序⼯⼚,则还需要额外的步骤。处理程序⼯⼚类实现 IHttpHandlerFactory 接⼝,此接⼝的 GetHandler⽅法将返回⼀个基于 IHttpHandler 的对象。
HTTP 运⾏时是如何结束这个循环并处理页⾯请求的?ProcessRequest ⽅法在 IHttpHandler接⼝中⾮常重要。通过对代表被请求页⾯的对象调⽤此⽅法,ASP.NET 结构会启动将⽣成浏览器输出的进程。
真正的 Page 类
特定页⾯的 HTTP 处理程序类型取决于 URL。⾸次调⽤ URL 时,将构建⼀个新的类,这个类被动态
编译为⼀个程序集。检查 .aspx 资源的分析进程的结果是类的源代码。该类被定义为命名空间 ASP 的组成部分,并且被赋予了⼀个模拟原始 URL 的名称。例如,如果 URL 的终点是 page.aspx,则类的名称就是 ASP.Page_aspx。不过,类的名称可以通过编程⽅式来控制,⽅法是在 @Page 指令中设置 ClassName 属性。
HTTP 处理程序的基类是 Page。这个类定义了由所有页⾯处理程序共享的⽅法和属性的最⼩集合。Page 类实现 IHttpHandler接⼝。
在很多情况下,实际处理程序的基类并不是 Page,⽽是其他的类。例如,如果使⽤了代码分离,就会出现这种情况。代码分离是⼀项开发技术,它可以将页⾯所需的代码隔离到单独的 C# 和 Microsoft Visual Basic® .NET 类中。页⾯的代码是⼀组事件处理程序和辅助⽅法,这些处理程序和⽅法真正决定了页⾯的⾏为。可以使⽤ <script runat=server> 标记对此代码进⾏内联定义,或者将其放置在外部类(代码分离类)中。代码分离类是从 Page继承并使⽤额外的⽅法的类,被指定⽤作 HTTP 处理程序的基类。
还有⼀种情况,HTTP 处理程序也不是基于 Page 的,即在应⽤程序配置⽂件的 <pages> 部分中,包含了 PageBaseType属性的重新定义。
<pages PageBaseType="Classes.MyPage, mypage" />
PageBaseType 属性指明包含页⾯处理程序的基类的类型和程序集。从 Page导出的这个类可以⾃动赋予处理程序扩展的⾃定义⽅法和属性集。
页⾯的⽣命周期
完全识别 HTTP 页⾯处理程序类后,ASP.NET 运⾏时将调⽤处理程序的 ProcessRequest ⽅法来处理请求。通常情况下,⽆需更改此⽅法的实现,因为它是由 Page类提供的。
此实现将从调⽤为页⾯构建控件树的 FrameworkInitialize ⽅法开始。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 ⽅法
处理回发事件由控件定义的任意回发事
件任意实现 IPostBackDataHandler 接⼝的控件中的 RaisePostBackEvent ⽅法
页⾯显⽰前阶段PreRender
保存视图状态SaveViewState
显⽰页⾯Render
卸载页⾯Unload
以上所列的阶段中有些在页⾯级是不可见的,并且仅对服务器控件的编写者和要创建从 Page 导出的类的开发⼈员有意义。Init、Load、PreRender、Unload,再加上由嵌⼊式控件定义的所有回发事件,就构成了向外发送页⾯的各个阶段标记。
执⾏的各个阶段
页⾯⽣命周期中的第⼀个阶段是初始化。这个阶段的标志是 Init 事件。在成功创建页⾯的控件树后,将对应⽤程序触发此事件。换句话说,当 Init 事件发⽣时,.aspx 源⽂件中静态声明的所有控件都已实例化并采⽤各⾃的默认值。控件可以截取 Init事件以初始化在传⼊的 Web 请求的⽣命周期内所需的所有设置。例如,这时控件可以加载外部模板⽂件或设置事件的处理程序。请注意,这时视图状态信息尚不可⽤。
初始化之后,页⾯框架将加载页⾯的视图状态。视图状态是名称/值对的集合,在此集合中,控件和页⾯本⾝存储了对所有 Web 请求都必须始终有效的全部信息。视图状态代表了页⾯的调⽤上下⽂。通常,它包含上次在服务器上处理页⾯时控件的状态。⾸次在会话中请求页⾯时,视图状态为空。默认情况下,视图状态存储在静默添加到页⾯的隐藏字段中,该字段的名称是 __VIEWSTATE。通过覆盖LoadViewState ⽅法(Control类的受保护、可覆盖⽅法),组件开发⼈员可以控制视图状态的存储⽅
式以及视图状态的内容映射到内部状态的⽅式。
有些⽅法(如 LoadPageStateFromPersistenceMedium 以及其对应的 SavePageStateToPersistenceMedium),可以⽤来将视图状态加载并保存到其他存储介质(例如会话、数据库或服务器端⽂件)中。与 LoadViewState 不同,上述⽅法只能在从 Page导出的类中使⽤。
存储视图状态之后,页⾯树中控件的状态与页⾯最后⼀次显⽰在浏览器中的状态相同。下⼀步是更新它们的状态以加⼊客户端的更改。处理回发数据阶段使控件有机会更新其状态,从⽽准确反映客户端相应的 HTML 元素的状态。例如,服务器的 TextBox 控件对应的 HTML 元素是 <input type=text>。在回发数据阶段,TextBox 控件将检索 <input> 标记的当前值,并使⽤该值来刷新⾃⼰内部的状态。每个控件都要从回发的数据中提取值并更新⾃⼰的部分属性。TextBox 控件将更新它的 Text 属性,⽽ CheckBox 控件将刷新它的 Checked属性。服务器控件和 HTML 元素的对应关系可以通过⼆者的 ID 到。
在处理回发数据阶段的最后,页⾯中的所有控件的状态都将使⽤客户端输⼊的更改来更新前⼀状态。这时,将对页⾯触发 Load事件。
页⾯中可能会有⼀些控件,当其某个敏感属性在两个不同的请求中被修改时,需要完成特定的任务。
例如,如果 TextBox 控件的⽂本在客户端被修改,则此控件将触发 TextChanged 事件。每个控件在其⼀个或多个属性被修改为客户端输⼊的值时都可以决定触发相应的事件。对于这些更改对其⾮常关键的控件,控件实现 IPostBackDataHandler 接⼝,此接⼝的 LoadPostData ⽅法是在 Load 事件后⽴即调⽤的。通过对 LoadPostData⽅法进⾏编码,控件将验证⾃上次请求后是否发⽣了关键更改,并触发⾃⼰的更改事件。
页⾯⽣命周期中的关键事件是被调⽤以执⾏服务器端代码的事件,此代码与客户端触发的事件相关联。当⽤户单击按钮时,将回发页⾯。回发值的集合中包括启动整个操作的按钮的 ID。如果控件实现 IPostBackEventHandler 接⼝(如按钮和链接按钮),页⾯框架将调⽤
asp查看源码配置ui
处理完回发事件之后,页⾯就可以显⽰了。这个阶段的标志是 PreRender 事件。控件可以利⽤这段时间来执⾏那些需要在保存视图状态和显⽰输出的前⼀刻执⾏的更新操作。下⼀个状态是 SaveViewState,在此状态中,所有控件和页⾯本⾝都将更新⾃⼰ ViewState集合的内容。然后,将得到序列化、散列、Base64 编码的视图状态,⽽且此视图状态与隐藏字段 __VIEWSTATE 相关联。
通过覆盖 Render ⽅法可以改变各个控件的显⽰机制。此⽅法接受 HTML 书写器对象,并使⽤此对象来积累所有要为控件⽣成的 HTML ⽂本。Page 类的 Render ⽅法的默认实现包括对所有成员控件的递归调⽤。对于每个控件,页⾯都将调⽤ Render⽅法,并缓存 HTML 输出。
页⾯⽣命中的最后⼀个标志是 Unload事件,在页⾯对象消除之前发⽣。在此事件中,您应该释放所有可能占⽤的关键资源(例如⽂件、图形对象、数据库连接等)。
在此事件之后,也就是最后,浏览器接收 HTTP 响应数据包并显⽰页⾯。
⼩结
ASP.NET 页⾯对象模型因其事件机制⽽显得格外新颖独特。Web 页⾯由控件组成,这些控件既可以产⽣丰富的基于 HTML 的⽤户界⾯,⼜可以通过事件与⽤户交互。以前,在 Web 应⽤程序的上下⽂中设置事件模型是件有挑战性的⼯作。可我们惊奇的看到,客户端⽣成的事件可以由服务器端的代码来解决,⽽且只进⾏⼀些相应的修改后,此过程仍可以输出相同的 HTML 页⾯。
掌握这个模型对于了解页⾯⽣命周期的各个阶段,以及页⾯对象如何被 HTTP 运⾏时实例化并使⽤是⾮常重要的。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。