ASP.NET页面生命周期包括哪几个阶段
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ASP.NET页面生命周期包括哪几个阶段相关的知识,希望对你有一定的参考价值。
当一个页面请求被发送到Web服务器时,不论该事件是由页面提交还是由页面重定向而激发的,页面在其创建到释放的过程中都会运行一系列的事件。1. 对象的初始化Init:页面初始化的标志是Init事件。页面中的控件(包括压面本事)都是在它们最初的Form中被首次初始化的。在成功创建页面的控件树后,对应用程序激发这个事件。当Init事件发生时,在.aspx源文件中静态声明的所有控件都已实例化并取其默认值。这时还没有视图状态信息可供使用。虽然可以重载OnInit方法,但是系统并不保证这些控件实例是按怎样的顺序被创建的。
2. 加载视图:在初始化之后,页面框架立即加载该页面的视图状态(ViewState)。所谓视图状态就是一些名称/值对的集合,例如可以保存TextBox控件的ID和Text属性值。它一般被用于在一个往返行程中存留信息到服务器,即参与HTTP请求与相应。页视图状态被存储在<input type="hidden">字段中,作为_VIEWSTATE的值进行记录。该视图状态通过ASP.NET自动维护。通过重写LoadViewState方法组件,开发人员可控制如何还原视图状态以及如何将其内容映射到内部状态。LoadViewState方法就是从ViewState中获取上一次的状态,并按照页面的控件树的结构,用递归来遍历整个树,将对应的状态恢复到每一个控件上。
3. 处理回发数据:还原了视图状态,页面树中的各个控件的状态就与浏览器上次呈现该页面时这些控件所处的状态相同。下一步需要更新这些控件的状态以发送给客户端。回发数据处理阶段使各个控件有机会更新其状态,以便准确地反映相应的html元素在客户端的状态。例如,一个服务器TextBox控件对应的HTML元素是<input type=text>,在回发数据阶段,TextBox控件将检索<input>标记的当前值并用它刷新其内部状态。每个控件负责从已发送的数据库中提取相应值,并更新其某些属性。TextBox控件将更新其Text属性,而CheckBox控件将刷新其Checked属性。服务器控件和HTML元素之间的匹配关系由二者的ID确定。页框架将在每个提交数据的控件上实现IPostBackDataHandler接口,然后激发LoadPostData事件,通过页面解析发现实现IPostBackDataHandler接口的控件,这样就能正确地回传数据更新控件的状态。在识别控件时,ASP.NET通过匹配控件的唯一标识符来更新正确地控件,该标示符具有名称值集合中的名称值对。这也就是在所有特定的页中每个控件都需要一个唯一标识符的原因之一。其他的步骤都由框架来完成,例如确定每个标志符在环境中是否唯一以及控件的基本属性等。LoadPostData方法的原型如下:
public virtual bool LoadPostData(string postDataKey,NameValueCollection postCollection)
postDataKey是标志控件的关键字,可以理解为控件的ID,postCollection是包含回发数据的集合,可以理解为视图状态值。该方法返回一个bool值,如果是true,则表示控件状态因回发而更改;否则返回false。页框架会跟踪所有返回true的控件,并在这些控件上调用RaisePostDataChangedEvent事件。LoadPostData方法是由System.Web.WebControls.Control定义的,而添加的每一个服务器控件也是从System.Web.WebControls.Control继承的,所以对于数据的回发处理并不需要干预。
4. 加载页面Load:在回发数据处理阶段结束时,页面中的所有控件都根据客户端上所输入的更改来更新原先的状态。此时,对页面激发OnLoad事件。用Visual Studio.Net生成的页面中的Page_Load方法就是响应Load事件的方法,对于每一次请求,Load事件都会触发,Page_Load方法也就会执行。可以利用该方法执行一些页面初始化。在事件引用中,为了提高性能,通常使用Page类的IsPostBack属性判断是不是数据回发。
5. 回发更改通知RaisePostDataChanged:如3所述,在所有实现了IPostBackDataHandler接口的控件被正确地回传数据更新后,每个控件都有一个布尔值的标识,标示其自上一次提交后该控件的数据是被更改还是保持原值。然后ASP.NET通过搜索页来寻找任何显示控件数据被更改的标识并激发RaisePostDataChanged。RaisePostDataChanged事件直到Load事件发生后,所有控件被更新后才激发。这保证了在控件被回传数据更新前,其他控件的数据在RaisePostDataChanged中没有被手动更改过。虽然也可以在Page的基础上自己定义数据更改的事件,但通常这个事件没有太大用处。
6. 处理回发事件RaisePostBackEvent:当回传更新导致数据改变而引发服务器端事件后,引发回传的对象会在RaisePostBackEvent事件中被处理。这种激发回传的对象往往是一个按钮被单击或者其状态改变而引发回传的控件。例如Button触发了OnClick事件、客户端修改了某个文本框的文本。同时将AutoPostBack设置为true、触发TextChanged事件等。很多代码都在这个事件中执行,因为这是控制事件驱动逻辑的理想位置。为了保证呈现到浏览器的数据的正确性,在一系列的回传事件后,RaisePostBackEvent事件最终被激发。基于一致性的考虑,回传中改变的控件直到这个函数被执行后才被更新。在实际的ASP.NET开发中要做的工作就是在此事件发生前处理代码,例如:
private void Button1_Click(object sender,System.EventArgs e)
Label1.Text="Hello!";
由于通过AutoPostBack属性可以触发RaisePostBackEvent事件,所以为了减轻服务器的负荷,尽量少用AutoPostBack="true"属性。触发服务器事件是在Page的Load之后,也就是说页面会先执行Page_Load,然后才会执行按钮(以按钮为例)的单击事件,通常都是在Page_Load中绑定数据,然后在按钮事件中处理更改,这样Page_Load永远都是在按钮事件之前执行,那么意味着数据还没来得及更改,Page_Load中的数据绑定的代码就先执行了,原有的数据又赋予了控件,执行按钮事件时,实际上获得的是原有的数据,数据仍然没有更新。
7. 预呈现PreRender:在处理回发事件后,页面就准备进行呈现。这一阶段的标志是PreRender事件。各个控件可利用这个很好的时机,以便执行任何需要在保存视图状态和呈现输出结果的前一刻完成最后一些更新操作。最终请求的处理都会转变为发回服务器的响应,预呈现这个阶段就是执行在最终呈现之前所做的状态的更改,因为在呈现一个控件之前,必须根据它的属性来产生HTML,比如Style属性。在预呈现之前,可以更改一个控件的Style,当执行预呈现时,就可以把Style保存下来,作为呈现阶段显示HTML的样式信息。
8. 保存状态SaveViewState:在这一状态中所有控件以及页面本身可以刷新自己的ViewState集合的内容。所得到的视图状态随后得以序列化、进行哈希运算、进行Base64编码并关联到VI-EWSTATE隐藏字段。
9. 呈现视图Render:在Render事件中,页调用对象使它们呈现为HTML,然后页收集HTML发送给客户。客户接收到HTML标记后进行重组,最终显示给用户。当Render事件被重载时,开发者可以为浏览器创建定制的HTML,此时页面创建的任何HTML都还没有生效。Render方法用HtmlTextWrite对象作参数并由它产生HTML送给浏览器。这主要用于自定义控件的开发。
10. 处置Disposed:执行销毁控件前的所有最终清理操作。在此阶段必须释放对昂贵资源的引用,如内存的退出、数据库的连接等。
11. 卸载Unload:一个页面的最后生存标志就是Unload事件,该事件在页面对象被解除之前发生。在此事件中,可以调用Dispose方法尽可能释放占用的任何关键资源(例如,文件、图形对象以及数据库连接)。
以上就是ASP.NET页面的生存周期。 参考技术A Microsoft shows us the basic steps of the ASP.NET page lifecycle below.
•S – Start
•I – Initialize
•L – Load
•V – Validate
•E – Event Handling
•R – Render
以上是关于ASP.NET页面生命周期包括哪几个阶段的主要内容,如果未能解决你的问题,请参考以下文章