执行的各个阶段
页面生命周期中的第一个阶段是初始化。这个阶段的标志是 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 接口(如按钮和链接按钮),页面框架将调用 RaisePostBackEvent 方法。此方法的行为取决于控件的类型。就按钮和链接按钮而言,此方法将查找 Click 事件处理程序并运行相关的委托。
处理完回发事件之后,页面就可以显示了。这个阶段的标志是 PreRender 事件。控件可以利用这段时间来执行那些需要在保存视图状态和显示输出的前一刻执行的更新操作。下一个状态是 SaveViewState,在此状态中,所有控件和页面本身都将更新自己 ViewState 集合的内容。然后,将得到序列化、散列、Base64 编码的视图状态,而且此视图状态与隐藏字段 __VIEWSTATE 相关联。
通过覆盖 Render 方法可以改变各个控件的显示机制。此方法接受 HTML 书写器对象,并使用此对象来积累所有要为控件生成的 HTML 文本。Page 类的 Render 方法的默认实现包括对所有成员控件的递归调用。对于每个控件,页面都将调用 Render 方法,并缓存 HTML 输出。
页面生命中的最后一个标志是 Unload 事件,在页面对象消除之前发生。在此事件中,您应该释放所有可能占用的关键资源(例如文件、图形对象、数据库连接等)。
在此事件之后,也就是最后,浏览器接收 HTTP 响应数据包并显示页面。
asp.net web生命周期
Asp.net相对以前的asp有了很大的发展.引用许多新的机制.本文是关于一个asp.net web生命周期的一个初步介绍.
当一个获取网页的请求(有可能是通过用户提交,或者是通过用户点击链接完成)被提交到服务器后.紧接着这个web页面就开始运行从创建到处理完成的一系列事件.在我们建立asp.net页面的时候,这个过程我们是不必去考虑的.然而,如果被正确的操纵,一个页面的执行周期将是一道有效而且功能强大的工具。许多开发者在编写Asp.net的页面以及用户控件的时候发现,如果知道整个过程中发生了什么以及在什么时候发生将对完成整个任务起到很重要的帮助作用。下面我就向大家介绍一下一个Asp.net页面从创建到处理完成过程中的十个事件。同时,也向大家展示如何在这些事件中添加自己的代码以达到预定的效果。
一、初始化对象
一个页面的控件(以及页面本身)最初应被正确的初始化。通过在你的C#文件的构造函数中声名所有对象,页面就知道要创建多少对象以及它们的类型。一旦你在你的构造函数中声名了所有的对象,你就可以通过继承类、方法、事件或是属性访问它们。然而,如果你的一些对象是在Aspx文件中指定的一些控件,那么这些控件就没有属性可言了。同时,通过代码访问它们会产生一些意外的错误,因为这些控件实例是没有一个确定的创建顺序的(如果它们是被一起创建的)。还有,你可以通过OnInit来重载初始化事件.
二、导入Viewstate数据
在初始化事件后,所有控件只可以通过它们的ID被引用访问(因为还没有相应的DOM可使用)。在LoadViewState这个事件中,所有的控件将获得它们的第一个属性:Viewstate属性。这个属性最终将被返回给服务器以判断这个页面是已经被用户访问完毕还是仍然在被用户所访问。Viewstate属性以“名称/值”对的字符串方式被保存,它包含了控件的文本以及值等信息。该属性被存储在一个隐藏的<input type="hidden" />控件的值属性里,在请求页面的时候被传递。还可以重载LoadViewState事件函数来对相应的控件进行值设定.如图:
联单
三、用LoadPostData处理Postback数据
在页面创建的这个阶段,服务器对页面上的控件提交的表单数据(在Asp.net中称postback数据)进行处理。当一个页面提交一个表单时,框架就在每个提交了数据的控件上执行一个IPostBackDataHandler接口操作。然后页面执行LoadPostData事件,解析页面,找到每个执行了IpostBackDataHandler接口操作的控件,并用恰当的postback数据更新这些控件状态。Asp.net是通过用NameValue集中的“名称/值”对和每个控件的唯一的ID匹配来实现这一操作的。所以,在Asp.net的页面上每个控件必须有一个唯一的ID,不可以出现几个控件共有ID的情况。即使是用户自定义的一些控件,框架也会赋予它们各自唯一的ID的。在LoadPostData事件后,就要执行下面的RaisePostDataChanged事件了。
四、导入对象
在Load事件中,对象都实例化了。所有的对象第一次被布置在DOM页面(在Asp.net中称控件树)里了并且可以通过代码或是相关的位置被引用。这样,对象就可以很容易的从客户端获得诸如宽度、高度、值、可见性等在Html中的属性值。在Load事件中,当然还有像设置控件属性等操作的发生。这个过程是整个生命周期中最重要、最主要的,你可以通过调用OnLoad来重载Load事件。如图:
五、RaisePostBackChanged事件
就像在上面提到的那样,这个事件是发生在所有的控件执行了IPostBackDataHandler接口操作并被正确的postback数据更新后的。在这个过程中,每个控件都被赋予一个布尔值来标志该控件有没有被更新。然后,Asp.net就在整个页面上寻找任何已被更新过的控件并执行RaisePostDataChanged事件操作。不过,这个事件是要在所有的控件都被更新了以及Load事件完成后才进行的。这样就保证了一个控件在被postback数据更新前,别的控件在RaisePostDataChanged事件中是不会被手动改变的。
六、处理客户端PostBack事件
当由postback数据在服务器端引起的事件都完成后,产生postback数据的对象就执行RaisePostBackEvent事件操作。可是会有这种情况,由于一个控件状态的改变使得它将表单返回给服务器或是用户点击了提交按钮使得表单返回给服务器。在这种情况下应该有相应的处理代码来体现事件驱动这一面向对象(OOP)编程原则。由于要满足呈现给浏览器的数据的精确性要求,在一系列postback事件中RaisePostBackEvent事件是最后发生的。在postback过程中改变的控件不应在执行功能函数被调用后更新。也就是说,任何由于一个预期的事件而改变的数据应该在最终的页面上被反映出来。你可以通过修改RaisePostBackEvent函数来满足你的要求.
七、预先呈递对象
可以改变对象并将改变保存的最后时刻就是这一步――预先呈递对象。这样,你可以在这一步对控件的属性、控件树结构等作出最后的修改。同时还不用考虑Asp.net对其作出任何改变,因为此时已经脱离了数据库调用以及viewstate更新了。在这一步之后,对对象的所有修改将最终被确定,不能被保存到页面的viewstate中了。你可以通过OnPreRender来重载这一步。
八、保存ViewState
所有对页面控件的修改完成后viewstate就被保存了。对像的状态数据还是保留在隐藏的<input type="hidden" />控件里面,呈现给Html的对象状态数据也是从这里取得的。在SaveViewState事件中,其值能被保存到viewstate对象,然而这时在页面上控件的修改却不能了。你可以用SaveViewState来重载这一步.如图:
九、呈递给HTML
运用Html创建给浏览器输出的页面的时候Render事件就发生了。在Render事件过程中,页面调用其中的对象将它们呈递给Html。然后,页面就可以以Html的形式被用户的浏览器访问了。当Render事件被重载时,开发者可以编写自定义的Html代码使得原先生成的Html都无效而按照新的Html来组织页面。Render方法将一个HtmlTextWriter对象作为参数并用它将Html在浏览器上以网页的形式显示。这时仍然可以做一些修改动作,不过它们只是客户端的一些变化而已了。你可以重载Render事件.如图:
十、销毁对象
在呈递给Html完成后,所有的对象都应被销毁。在Dispose事件中,你应该销毁所有在建立这个页面时创建的对象。这时,所有的处理已经完毕,所以销毁任何剩下的对象都是不会产生错误的,包括页面对象。你可以重载Dispose事件.
全文总结: