[Joe 原创]Web Control 开发系列(一) 页面的生命周期

上传人:油条 文档编号:28571018 上传时间:2018-01-18 格式:DOC 页数:17 大小:213KB
返回 下载 相关 举报
[Joe 原创]Web Control 开发系列(一) 页面的生命周期_第1页
第1页 / 共17页
[Joe 原创]Web Control 开发系列(一) 页面的生命周期_第2页
第2页 / 共17页
[Joe 原创]Web Control 开发系列(一) 页面的生命周期_第3页
第3页 / 共17页
[Joe 原创]Web Control 开发系列(一) 页面的生命周期_第4页
第4页 / 共17页
[Joe 原创]Web Control 开发系列(一) 页面的生命周期_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《[Joe 原创]Web Control 开发系列(一) 页面的生命周期》由会员分享,可在线阅读,更多相关《[Joe 原创]Web Control 开发系列(一) 页面的生命周期(17页珍藏版)》请在金锄头文库上搜索。

1、Joe 原创Web Control 开发系列(一) 页面的生命周期 Page 是 WebForm 编程基本元素,它从 TemplateControl 派生,而TemplateControl 又从 Control 派生,所以 Page 实际就是一个 Control。同时Page 也实现了 IHttpHandler 接口,所以它可以接受 Http 请求,进行处理。可以认为一个 Page 是由很多的 Control 按照树形结构组织的,而树的根就是Page(一个实现了 IHttphandler 的 Control), 整个 Control 树的生命周期开始于一个 Http 请求,而终止于请求处理的结

2、束。事实上在 Http 请求传入到当前的 Page 的时候,之前已经经过了漫长的路程,如果对于整个 Http 请求的细节感兴趣,可以查看 MSDN 中关于应用程序的生命周期 。另外关于页面的生存周期也有很多的文章可以参考,比如 MSDN 中 ASP.NET 页生命周期概述。我这里主要讲讲我个人的理解,如果有什么不妥的地方,欢迎大家指正。Page 存在的目的就是对于用户的内容进行呈现,它是一个IHttpHandler,它实现了对 HttpRequest 的处理,这个处理的结果就是根据请求 Render 出它自己,而 Render 的内容就是 Html,CSS,Javascript,这些东西最终成

3、为表现 Page 样子的一砖一瓦。如果做一个最简单的实现,大概就是public class Page : IHttpHandlerpublic void ProcessRequest(HttpContext httpContext)Render();事实并非如此,如果这样的话,我们岂不是对于每个 Page 都要从零开始做一套完整的 Render 画法啊,那样的 Render 方法将是一个很长,很长的调用,为了支持不同的浏览器,为了应付复杂的业务逻辑,里面的代码将是魔鬼,也许写完一次没有人愿意维护了,而且代码的复用性也很低。那么怎么办呢?.net 为了解决这个问题,提供的是 Control 模型

4、,对于一个页面,页面本身是一个可以呈现自己的 Control,同事页面里面也可以任意嵌套其它的 Control,每个 Control 都具有呈现自己的能力,那样 Control 将具有很好的复用性和可维护性,任何一个开发人员可以任意组合来自于第三方的 Control 来构建自己的 Page。所以就需要有一个 Control 的类,而且 Page 是 Control 的一个派生类。Page 的 Render 方法需要递归调用 RenderChildren,这样让整个 Control树一层一层的呈现,最后得到整个 Page 的样子。我们知道 Http 请求里面有 Get 和 Post,对于 Get

5、 往往是请求一个全新的页面,对于 Post 更多的是客户端的一个响应。对于 Get 的请求,我们可以从零开始 Render 一个新的 Page 给客户端。但是对于 Post,我们一般需要让页面恢复到客户端看到的状态,然后再出来 Post 的数据。正是由于这个原因,Page在 ProcessRequest 的过程中不得不区分 Page.IsPost or not。而如何进行场景恢复呢,这大概就是 ViewState 产生的真正原因了, ViewState 是 Control 上的一个存储结构。它负责保存 Control 的一些状态。这些状态通常会被序列化到客户端的页面上,当客户端的页面发出 Po

6、st 请求的时候,.net 生产的脚本会自动收集这些 ViewState 数据,然后一起 Post 给服务器端。这样 Page 就可以加载这些状态进行场景恢复,然后在恢复好的场景下出来 PostData。所以在ProcessRequest 里面需要加入对于LoadViewState,SaveViewState,ProcessPostData 的处理。但是是否所有对于 Control 的设置都会序列化成 ViewState 呢,那样不是很影响性能吗,如果说我们每次在请求处理的开始阶段(无论是 Post 还是非Post)都用代码初始化 Control,不是就不需要利用 ViewState 加载状态

7、了啊?所以在 ProcessRequest 里面又有了新的过程的加入 Init,在 Init 里面可以设置Control 的一些属性和状态,而在 Init 以后才通过 TrackViewState 来通知Control,TrackViewState 阶段后对 Control 的修改才会 SaveViewState 的时候保存下来,否则都不保存。类似的例子还有很多,就像我们自己做的软件产品,很多时候,第一个版本都是简单的,以后随着需求的增加,代码越来越多,结构越来越复杂,也许未来版本的 Page 还会有更多的变化,总之经过很多的需求,Page 对于Request 的处理就变得复杂了,最后就分为下

8、面的几个阶段,关于这些阶段的介绍,我们可以在 Google 上搜索很多的文章,我认为我们不仅仅要了解这些阶段,还要深入理解,否则想做出好的 Control 是很困难的。代码中的数字列出了主要的页面生命周期的阶段,对于 PostBack 和 CallBack,阶段会发生一些变化,也加了说明private void ProcessRequestMain(bool includeStagesBeforeAsyncPoint, bool includeStagesAfterAsyncPoint)/ 1. PreInitthis.PerformPreInit();/ 2. Initthis.InitRe

9、cursive(null);this.OnInitComplete(EventArgs.Empty);/ 对于 Postback,插入下面处理if (this.IsPostBack)/ 加载 ViewState 和 ControlState,进行场景恢复 this.LoadAllState();/ 第一次处理 PostDatathis.ProcessPostData(this._requestValueCollection, true);/ 3. PreLoadthis.OnPreLoad(EventArgs.Empty);/ 4. Loadthis.LoadRecursive();/ 对于

10、Postback,插入下面处理if (this.IsPostBack)/ 第二次处理 PostDatathis.ProcessPostData(this._leftoverPostData,false);/ 如果 PostData 表面某个 Control 数据发生变化,那么 RaisePostDataChanged 事件this.RaiseChangedEvents();/ RaisePostBackEventthis.RaisePostBackEvent(this._requestValueCollection); this.OnLoadComplete(EventArgs.Empty);

11、/ 对于 CallBack,RaiseCallBackEventif (this.IsPostBack & this.IsCallback)this.PrepareCallback(callbackControlID);else if (!this.IsCrossPagePostBack)/ 5. PreRenderthis.PreRenderRecursiveInternal();/ 对于 CallBack, Render 出 CallBack 的结果if (this.IsCallback)this.RenderCallback();else if (!this.IsCrossPagePos

12、tBack)this.PerformPreRenderComplete(); / 6. SaveViewStae 和 ControlStatethis.SaveAllState();this.OnSaveStateComplete(EventArgs.Empty);/ 7. Render 整个 Controlthis.RenderControl(this.CreateHtmlTextWriter(this.Response.Output);1. PreInit 阶段这个阶段是 Page 独有的,在 Control 上是没有的,这个阶段主要是.net Framework 自己在里面做了一些自己的

13、初始化工作,比如 Skin 的加载,MasterPage 的加载。会发 Page.OnPreInit 事件,源代码如下:private void PerformPreInit()this.OnPreInit(EventArgs.Empty);this.InitializeThemes();this.ApplyMasterPage();this._preInitWorkComplete = true;2. Init 阶段InitRecursive()是 Page 从 Control 继承的方法,它主要进行 Control 的一些初始化和标记工作a. 对当前 Control 进行准确初始化,包括:

14、 初始化_adapter; ApplySkin(this.Page); 设置标记 this._controlState = ControlState.Initialized; TrackViewState()/ 开始跟踪变化,这个阶段以后的变化会存入 ViewState b. 对子 Control 进行初始化 初始化 nameContainer 属性 初始化 page 属性 自动生成 Id 递归调用子 Control 的 InitRecursive()方法 有个值得注意的是,如果在 Control 树执行完 Init 之后创建一个新的Control 加入到树上,那么当它加入的时候,在父 Con

15、trol 的 AddedControl 方法里面,如果发现已经 Initialized,那么手动调用新加入 Control 的InitRecursive()方法。所以,我们 Control 的 Init 阶段给 Control 的一些需要查找才可以得到的属性进行直接赋值,如 Page,nameContainer,这样可以提高这些属性的访问速度。3. PreLoad 阶段仅仅发 Page 独有的事件:OnPreLoad 事件4. Load 阶段 LoadRecursive()是 Page 从 Control 继承的方法,它比较简单,仅仅是递归调用子 Control 的 LoadRecursive

16、()方法,然后做一个阶段标记: ( this._controlState = ControlState.Loaded) ; 5. PreRender 阶段PreRenderRecursiveInternal()是 Page 从 Control 继承的方法,这个方法会 EnsureChildControls()调用 CreateChildControls(),确保子 Control创建完毕,为接下来的 Render 做准备 递归调用子 Control 的 PreRenderRecursiveInternal() 6. SaveAllState 阶段主要存储 ControlState 和 ViewState,ControlState 和 ViewState 唯一不同的地方在于 ControlState 是不可以禁用的,而 View

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号