asp.net 页面生成过程详细介绍 以及asp.net2.0 Bryan 初始化 当页面被提交请求第一个方法永远是构造函数。您可以在构造函数里面初始一些自定义属性或 对象,不过这时候因为页面还没有被完全初始化所以多少会有些限制。 特别地,您需要使用 HttpContext 对象。当前可以使用的对象包括QueryString, Form 以及Cookies 集合,还有Cache 对象。注意:在构造函数里是不允许使用Session 的。 下一个将执行的方法是AddParsedSubObject 方法,这个方法将添加所有独立的控件并把页面组 成一个控件集合树,这个方法经常被 一些高级的页面模板解决方案(Page Template Solutions) 重写以便添加页面内容到页面模板(Page Template)中一些特殊的控件中。这个方法递归应用 到所有的页面控件及相应的的每个子控件,所有的控件都是在这个方法中开始最早的初始化。 页面类中下一个将执行的方法是DeterminePostBackMode。这个方法允许您修改IsPostBack 的 值及相关的事件。如果您需要从数据库中 加载ViewState 这个方法将特别有用,因为ViewState 只有在IsPostBack 为真的情况下才会进行恢复。返回空将会导致强制执行非回 传,返回 Request.Form 则强制执行一个回传。除非在特殊情况下,否则并不建议去操作这个,因为这个 还会影响其他的事件。 下一个将要执行的方法是OnInit 方法,一般这是第一个真正被使用的方法。这个方法触发时, 所有页面定义中的控件执行初始化,这意味着所有在 页面中定义的值应用到相应的控件上。不 过,ViewState 和传回的值还不会应用到控件上,因此,任何被代码或用户改变的值还没有被恢 复到控件上。这个 方法通常是最好的创建、重创建动态控件的好地方。 l 恢复及加载 下一个方法, LoadPageStateFromPersistenceMedium 只会在页面被回传的时候才会被执行。 如果因为使用Session 或自定义存储方 式,您修改了后面将要提到的影响ViewState 保存方式 的方法SavePageStateToPersistenceMedium,则这个方法需要被 重写。默认的实现中ViewState 是一种Base64 格式编码,并且被保存在页面的隐藏域中,您可以使用这篇文章中提及的方法修 改ViewState 按以上两种方式保存。注意:这个方法并没有真正加载ViewState 到页面或页面 控件中。 当得到ViewState 后,下一个方法LoadViewSate,将以递归的方式恢复ViewState 到页面及 各个页面控件或子控件中。这 个方法执行后,每个控件都将恢复到上一次的状态,但是用户提 交的数据还没有应用到控件上,因为他们不是ViewState 的一部分。这个方法主要用于恢复 您 在其他事件中动态生成的控件的值,他们的值是您手动保存在ViewSate 中,并且现在已经失效。 下一个方法是ProcessPostData,这个方法也同样是回传的时候才会被执行,并且不允许被重 写,这个是页面基类的私有方法。这个方法 通过匹配控件的名称恢复相应的用户提交的控件的 值,到这一步意味着整个页面都已经被完全恢复了。唯一要记住的是所有动态控件的创建必须在 这个方法之前。这 个方法也是记录后面的改变事件的方法。 下一个方法是OnLoad 方法,通常这是用得最多的方法,因为这个方法是页面生存期第一个恢 复了所有值的地方。大多数代码根据判断 IsPostBack 来决定是否重新设置控件状态。您也可以 在这个方法中调用Validate 并且检查IsValid 的值。也可以在这个方法中创建动态控 件,并且 该控件的所有的方法都会被执行以追上当前页面的状态包括ViewSate,不过不包括回传的值。 l 事件处理 下一个方法还是 ProcessPostData,实际上就是前一个方法的另一次调用,它仍然是只在回传 的时候执行并且由于是私有方法不可以被重写。如果您是第一次看页面 的运行轨迹也许会觉得 这个方法有些多余。但实际上这个方法是必要的因为在OnLoad 中创建的动态控件也需要他们回 传的值。任何在这以后创建的控件将可以 得到他们的ViewState,但是不能再得到他们的回传 的值,并且不会触发任何值改变事件(Change Event)。 下一个方法,RaiseChangedEvents,也是只在回传页面中执行,并且也因为是基类的私有方法 所有不能被继承。在整个页面生存期 中,是在这儿根据之前的ProcessPostData 记录的控件的 值和提交的值是否不同来触发值改变事件。您也许需要调用Validate 或者检查 IsValid 的值。 这里并没有特别的说明多个值改变事件的执行先后顺序。 下一个方法,RaisePostBackEvent,同样是因为是基类的私有方法不能被继承,同样也是只在 回传页面中执行。除非使用了AutoPostBack,不然这是实际提交表单事件执行的地方,特别是 按钮或者其实使用javascript 提交表单等。如果还没有被手动调用过并且使用了验证控件,那 么Validate 会被调用。注意IE 中有个BUG 有时会允许提交但却不触发任何事件。 下一个方法是OnPreRender,一般这是在客户端展现页面之前改变页面及其控件的最后一次机 会。您也可以在这个方法里面创建动态控件,并 且所有的方法都会被执行以追上当前页面的状 态包括ViewSate,但是私有方法将不会被执行,这意味着不会有回传的值并且不会有事件触发。 由于IE 中的 BUG,这是一个没有事件赶上PostBack 的好地方。 l 保存及显示 下一个方法是SaveViewState,不论是否是回传页面,均会递归的执行以保存页面及其所有控 件的ViewState。ViewState 基本上保存所有与定义在aspx 中的原始值不同的值,不管是被代码 还是用户所改变。注意控件值是根据他们在页面的控件树中的位置来保存的,所以如果动态控件 后来加到了错误的位置将会导致混乱。 下一个方法是SavePageStateToPersistenceMedium 真正的保存页面的ViewSate。这个方法随 同 LoadPageStateFromPersistenceMediumg 一起被重写以便保存ViewState 到Session 或其它 自定义数据,而不是用隐藏域。这对于低带宽的用户来说是很有帮助的。并且对于移动设备来说, Session 是默认设置。下面这篇文章描述了使用以上两种方式保存ViewState 的具体细节。注意 在Asp.net 中有个Bug:Asp.net 要求必须提交__viewstate 字段,即使是空的。 下一个方法是Render 方法,该方法递归的创建并发送相应控件的html 给浏览器。这个方法被 一些页面模板方案重写以添加一些通用的页面头与 脚而不使用服务器控件,他们总是有一些额 外的东西。注意这儿的修改只能使用纯HTML,因为控件在这儿已经被生成了。您可以用 StringBuilder,StringWriter,HtmlTextWriter 捕获相应的HTML 输出。 最后的方法是OnUnload,这个方法会调用相应的Dispose 方法。这个方法提供机会以便清空 该页面中使用的非托管资源,如关闭打开的文件句柄,以前打开的数据库连接等。注意这个方法 是在页面已经发送到客户端以后执行的,所以它只有影响服务器对象,并且它不会显示在页面的 显示轨迹中。这就是页面的生存期,对于每一次请求都是这么运行的。 l 作者简介(略) 表1:页面事件总结 方法回传控件 ConstructorAlwaysAll AddParsedSubObjectAlwaysAll DeterminePostBackModeAlwaysPage OnInitAlwaysAll LoadPageStateFromPersistenceMediumPostBackPage LoadViewStatePostBackAll ProcessPostData1PostBackPage OnLoadAlwaysAll ProcessPostData2PostBackPage RaiseChangedEventsPostBackPage RaisePostBackEventPostBackPage OnPreRenderAlwaysAll SaveViewStateAlwaysAll SavePageStateToPersistenceMediumAlwaysPage RenderAlwaysAll OnUnloadAlwaysAll 与 ASP.NET 1.x 相比,ASP.NET 2.0 提供了更精确的页面生命周期方法堆栈。这些新增的方法 为 Web 开发人员提供了更高级别的控制。可以通过任何 ASP.NET 页面上的“Page”对象访问这 些事件。 表 1 显示了全面的方法列表。“方法”列显示了实际的事件方法名称,“活动”列指示事件是 始终处于活动状态还是仅在 PostBack 操作期间处于活动状态。例如,可以使用新方法 TestDeviceFilter 来确定哪个设备筛选器可用,并使用此信息决定如何显示页面。换句话说, 新方法 LoadControlState 仅在回发期间调用。可以替代此方法(与 SaveControlState 结合 使用),以创建用于在回发期间保存和恢复控件状态的替换序列化方案。 表 1:页面生命周期方法 方法 活动 Constructor 始终 Construct 始终 TestDeviceFilter 始终 AddParsedSubObject 始终 DeterminePostBackMode 始终 OnPreInit 始终 LoadPersonalizationData 始终 InitializeThemes 始终 OnInit 始终 ApplyControlSkin 始终 ApplyPersonalization 始终 OnInitComplete 始终 LoadPageStateFromPersistenceMedium PostBack LoadControlState PostBack LoadViewState PostBack ProcessPostData1 PostBack OnPreLoad 始终 OnLoad 始终 ProcessPostData2 PostBack 表 1:页面生命周期方法 方法 活动 RaiseChangedEvents PostBack RaisePostBackEvent PostBack OnLoadComplete 始终 OnPreRender 始终 OnPreRenderComplete 始终 SavePersonalizationData 始终 SaveControlState 始终 SaveViewState 始终 SavePageStateToPersistenceMedium 始终 Render 始终 OnUnload 始终 通过查看页面生命周期的低级别详细信息,我们可以发现在何处能够自然地实现 ASP.NET 2.0 中的许多功能,例如主题和个性化。例如,可以在 IntializeThemes 事件中处理一个主题,在 LoadPersonalizationData 中加载个性化数据,并在以后应用于 ApplyPersonalization 方法。 请注意,对于决定 Web 应用程序的最终外观的 UI 元素而言,方法的顺序极其重要。
posted on 2008-09-26 02:26  sinjane  阅读(330)  评论(0)    收藏  举报