博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Asp.Net生命周期系列六
阅读量:5290 次
发布时间:2019-06-14

本文共 7852 字,大约阅读时间需要 26 分钟。

上篇说到当一个Http请求流到HttpHandler这里时才开始对它的处理,那么一个请求经过HttpHandler之后, 到底怎么对它处理呢,也就是说HttpHandler会触发哪些事件,触发的顺序如何,我们可以在此中间做些什么?

话说我们今天的重中之重:页面生命周期,说的就是Page类在处理页面的过程中都发生了哪些事件,而这些事件又是按照什么顺序发生的。ASP.NET的页面生命周期跟我们之前的理论讲解完全不同,它具有非常强大的实用性,所以我想通过一个小例子来进行解释和说明,以便让大家看起来更清晰和容易理解。因为Page类的ProcessRequest方法实现非常的复杂,我把代码反编译过来给大家看我觉得也没什么意义,所以我就着重给大家看一下整个页面的事件是以何种顺序被引发的,以及在这些事件中,我们能做什么。在这个过程中,我们主要关注如下问题:

1,    事件的执行顺序

2,    控件何时被初始化(我们什么时候能用它)

3,    ViewState何时可用

4,    更改MasterPageTheme

5,    在各个事件中还能干什么工作

 

按照如下步骤建立示例:

一,我们创建一个website

二,加入两个MasterPage分别为site.mastermap.master,分别在上面加一个label进行说明:this is site/map master page.

三,分别加入两个themeBlueSkinRedSkin,分别对button的背景色进行设置,一个是Blue,另外一个是Red

四,default页面中加入两个label和一个button

五,Default页面代码如下:

 

private int step = 1;  2     private string GetEventName(string eventName)  3     {  4         step += 1;  5         return eventName;  6     }  7   8     protected override void OnPreInit(EventArgs e)  9     { 10         base.OnPreInit(e); 11         Response.Write(GetEventName("pre init event, this is the " + step + "th step!")); 12         //lblMessage.Text = "on pre init"; 13  14         this.MasterPageFile = "map.master"; 15         this.Theme = "BlueSkin"; 16         if (lblMessage2 == null) 17         { 18             Response.Write("Server control has not been initialed on pre init"); 19         } 20         else 21         { 22             Response.Write("Server control has been initialed here"); 23         } 24         if(this.ViewState.Count>0) 25         { 26             Response.Write("ViewState can be used here, the ID is "+ViewState["ID"].ToString()); 27         } 28  29         Response.Write("
"); 30 } 31 protected override void OnInit(EventArgs e) 32 { 33 if (lblMessage2 == null) 34 { 35 Response.Write("Server control has not been initialed on pre init"); 36 } 37 else 38 { 39 Response.Write("Server control has been initialed here"); 40 } 41 base.OnInit(e); 42 43 Response.Write(GetEventName("init event, this is the " + step + "the step! ")); 44 if (lblMessage2 == null) 45 { 46 Response.Write("Server control has not been initialed on pre init"); 47 } 48 else 49 { 50 Response.Write("Server control has been initialed here"); 51 } 52 if (this.ViewState.Count > 0) 53 { 54 Response.Write("ViewState can be used here, the ID is " + ViewState["ID"].ToString() + ""); 55 } 56 Response.Write("
"); 57 58 //this.MasterPageFile = "map.master"; 59 //this.Theme = "BlueSkin"; 60 } 61 protected override void OnInitComplete(EventArgs e) 62 { 63 base.OnInitComplete(e); 64 Response.Write(GetEventName("init complete event, this is the " + step + "th step!")); 65 if (this.ViewState.Count > 0) 66 { 67 Response.Write("ViewState can be used here, the ID is " + ViewState["ID"].ToString() + ""); 68 } 69 else 70 { 71 Response.Write("ViewState can not be used here"); 72 } 73 Response.Write("
"); 74 } 75 protected override void OnPreLoad(EventArgs e) 76 { 77 if (this.ViewState.Count > 0) 78 { 79 Response.Write("ViewState can be used here, the ID is " + ViewState["ID"].ToString() + ""); 80 } 81 else 82 { 83 Response.Write("ViewState can not be used here"); 84 } 85 base.OnPreLoad(e); 86 Response.Write(GetEventName("pre load event, this is the " + step + "th step!")); 87 if (this.ViewState.Count > 0) 88 { 89 Response.Write("ViewState can be used here, the ID is " + ViewState["ID"].ToString() + ""); 90 } 91 else 92 { 93 Response.Write("ViewState can not be used here"); 94 } 95 Response.Write("
"); 96 } 97 protected void Page_Load(object sender, EventArgs e) 98 { 99 Response.Write(GetEventName("page load system provided, this is " + step + "th step!"));100 if (this.ViewState.Count > 0)101 {102 Response.Write("ViewState can be used here, the ID is " + ViewState["ID"].ToString() + "");103 }104 Response.Write("
");105 }106 107 protected override void OnLoadComplete(EventArgs e)108 {109 base.OnLoadComplete(e);110 Response.Write(GetEventName("on load complete event, this is the " + step + "th step!
"));111 }112 113 protected override void OnPreRender(EventArgs e)114 {115 base.OnPreRender(e);116 Response.Write(GetEventName("pre render event, this is the " + step + "th step!
")); 117 }118 119 protected override void OnPreRenderComplete(EventArgs e)120 {121 base.OnPreRenderComplete(e);122 Response.Write(GetEventName("pre render complete event, this is the " + step + "th step!
"));123 }124 125 protected override void OnSaveStateComplete(EventArgs e)126 {127 128 base.OnSaveStateComplete(e);129 Response.Write(GetEventName("sae state complete event, this is the " + step + "th step!
"));130 }131 132 protected override void Render(HtmlTextWriter writer)133 {134 base.Render(writer);135 Response.Write(GetEventName("render function, this is the " + step + "th step!
"));136 }137 138 protected override void OnUnload(EventArgs e)139 {140 if (this == null)141 {142 string aaa = string.Empty;143 }144 if (lblMessage2 == null)145 {146 string ga = string.Empty;147 }148 base.OnUnload(e);149 if (this == null)150 {151 152 }153 }154 155 protected override void OnLoad(EventArgs e)156 {157 base.OnLoad(e);158 Response.Write(GetEventName("page load we created, this is the " + step + "th step!
"));159 }160 protected void btnSubmit_Click1(object sender, EventArgs e)161 {162 ViewState["ID"] = "12345";163 Response.Write(GetEventName("button control click event, this is the " + step + "th step!
"));164 }

 

执行结果:

 

七,代码分析

a)         从执行结果我们可以看到,事件的执行顺序为:

                         i.              PreInit

                       ii.              Init

                      iii.              InitComplete

                      iv.              PreLoad

                       v.              Load

                      vi.              Control Event(if they have)

                    vii.              LoadComplete

                   viii.              PreRender

                      ix.              PreRenderComplete

                       x.              SaveStateComplete

                      xi.              Render

                    xii.              Unload

 

b)         从结果中我们也可以看到,在PreInit事件发生后控件还没有被初始化,也就是我们还不能使用。而在Init刚刚发生的时候已经可以使用了。也就是说,控件初始化发生在PreInit之后Init之前。总而言之,我们关心的是我们最早可以在Init事件里对页面server端控件进行操控。

c)         关于ViewState,本示例也清晰的显示出它在Init Complete之后还是不能使用,而在PreLoad刚刚发生的时候,就已经可以使用了。

d)         通过对比Default.aspx页面的配置我们知道,在PreInit里面的ThemeMasterPage的设置是生效了的,我们可以在PreInit里设置ThemeMasterPage,而在其它任何位置设置这两个东西都将抛出异常(看我注视掉的代码)

e)         其它的事件:

Load: 这个事件可能是大家最熟悉的了。需要注意的是,Page对象会递归的调用子控件的onload事件直到页面和所有的子控件被加载完成。这个事件主要用来设置控件属性的值,建立数据库连接(通常不这么做)。

Control events: 这个就不多说了,主要是处理控件的事件,例如click。这也就让我们明白了每次我们click一个Button的时候,实际上是要先去执行load事件然后才执行click事件的,一般我们用!IsPostBack来判断一下从而避免执行不必要的加载逻辑。

LoadComplete: 页面所有的控件都被加载以后执行,暂时没有想到用来干什么。。。

PreRender: HTML被生成之前这是最后一个事件。每一个页面中的控件都有PreRender的过程。在这里对将要输出的HTML结果进行最后一次修改。

SaveStateComplete: 在这个时间发生之前,已经保存了所有控件和页面的,任何对page或者控件的改动都不会产生左右。暂时没想到用来干啥。

Render: 它不是一个事件而是一个方法。工作就是把HTML写回客户端浏览器。

UnLoad: 页面中的每一个控件都会发生这件事。在控件中,使用这个事件来做清理工作,例如关闭数据库连接等。对与页面本身也是做清理工作,例如关闭打开的文件和数据库连接,或者结束日志或者其它指定的工作。

f)          关于Unload事件,它实际上做的是销毁前的工作。在Unload事件发生以后,Page类被卸载和销毁,所以page类的字段值也就消失了,而我们通常也是使用在SaveStateComplete之前保存的ViewState来存储哪些我们想要存储的page里的数据。HttpRuntime做了销毁Page的动作,同样也是它创建的Page这个handler,现在我们知道原来不是HttpApplication雇佣了P_Handler, HttpApplication只是使用了它而已,真正雇佣(创建)并解雇(销毁)P_Handler的是老板HttpRuntime

 

整个ASP.NET生命周期基本结束,如果大家想更深入的了解其中内情,请反编译System.Web.HttpRuntime类。如果您不喜欢研究那么深入,我想我这几篇文章应该可以对您有些帮助。

 

 

 

转载于:https://www.cnblogs.com/skm-blog/p/3219528.html

你可能感兴趣的文章
PHP的分页
查看>>
ZOJ 3791 An Easy Game [组合计数]
查看>>
DOM
查看>>
AOJ/搜索与递归及分治法习题集
查看>>
express
查看>>
iOS视图弹出、平移、旋转、翻转、剪切等变换效果实现
查看>>
iOS获取用户设备崩溃日志并分析
查看>>
String类
查看>>
1、IO概述及File类
查看>>
[bzoj3531][Sdoi2014]旅行
查看>>
3.将模型添加到 ASP.NET Core MVC 应用
查看>>
Google TensorFlow for GPU安装、配置大坑
查看>>
【转】Android开发之如何保证Service不被杀掉(broadcast+system/app)
查看>>
什么是RUP,什么是敏捷开发,什么是XP(极限编程)
查看>>
DB9针和DB25针串口的引脚定义
查看>>
分段和分页内存管理
查看>>
人工智能教程
查看>>
Redis客户端连接异常
查看>>
小白学数据分析----->移动游戏的使用时长分析
查看>>
静态页面表单提交
查看>>