Asp.net页面生命周期描述

 

 

ASP.NET页面生命周期描述

下面是ASP.NET页面初始的过程:
1. Page_Init();页面初始化(所有控件都已实例化并取其默认值)
2. Load ViewState;加载视图状态(把请求的viewstate数据都还原过来)
3. Load Postback data;处理回发数据(浏览器发过来的数据加载过来)
4. Page_Load();加载页面

5.RaisePostDataChangeEvent方法;回发更改通知(如Textbox里面本来是aa,用户改成bb,点击按钮提交到服务器来,就检查控件的值有没有改变)

6.RaisePostBackEvent方法;处理回发事件(点击下拉框改变(有一个回传的过程)事件,对应服务器的方法)
7. Page_PreRender();页面预呈现(页面生成的html代码发送到浏览器之前,可以最后一次改变某些控件的样式表属性)

8.SavaViewState方法;保存视图状态(准备把数据发到浏览器去了,那么服务器端控件的属性全部要提出来序列化成字符,转成base64编码保存到viewstate里面去发到浏览器去,就是在这个方法里面做的)
9. Page_Render();呈现页面
10.Dispose;释放服务器资源
9. Unload;卸载页面

 

下面对其中的一些过程作下描述:
1. Page_Init();
这个过程主要是初始化控件,每次页面载入执行这个初始过程,包括第一次和以后的Postback(这里说下Postback,其实就可以简单理解成用户点击SUBMIT按钮之类的,把表单

提交给服务器,这就是一次postback),在这里面可以访问控件,但是这里面的控件值不是我们期待的控件里面的值,他只是一个控件的初始值(默认值),举例: 比如一个TextBox1,我们填入了"哈哈",在点击SUBMIT提交了页面后,在Page_Init()里面,我们访问到的TextBox1.Text不是我们的"哈哈",而是开始的""空字符串,如果TextBox1在我们设计的时候提供了默认值,这里访问到的也就是提供的默认值,为什么呢,这就要看下一个过程了.

对应的事件Page.Init

 

2. Load ViewState
这个过程是载入VIEWSTATE和Postback数据,比如我们上面的TextBox1,这时就赋了"哈哈",所以,在Post_Init()对控件赋值是无意义的,它都会在这个过程里被改写,当然第一次页面载入例外,因为没有VIEWSTATE数据。

没有对应的事件

 

3.Load Postback data;
上面说了,Postback可以理解成用户提交表单数据,所以这里就是处理表单数据,当然这里要设计到控件的设计,一般情况不会要我们自己处理这个过程,我们暂且略过. (在以前那篇关于ASP.NET页面生命周期的简单描述中,把这个过程和Load ViewState放在了一起,其实那是微软提供的生命周期过程,这里单独提出来是为了让大家明白这是一个单独的过程)
 没有对应的事件


4. Page_Load();
这个过程也是每次页面载入时一定会执行的,但是注意和Page_Init的区别,上面已经涉及了,这里注意的是一般都会用到Page.IsPostBack,该值指示该页是否正为响应客户端回发而加载,或者它是否正被首次加载和访问。
private void Page_Load(object sender, System.EventArgs e)
{
  if(!Page.IsPostBack)
  {
    //第一次执行的CODE HERE
  }
  else
  {
    //用户提交FORM(即Postback)CODE HERE
  }

  //每次这里的都回执行CODE HERE
}

对应的事件Page.Load

 

5. Handle control events;
这个过程里,相应具体的控件事件,比如private void ListBox1_SelectedIndexChanged(object sender, System.EventArgs e)事件等等

没有对应的事件(我们自己的事件函数都包括在这个过程里比如上面的ListBox1_SelectedIndexChanged)

 

6. Page_
预先呈递对象,这里是在向用户程序呈现数据的倒数第二步,我估计提供这个过程的意义,也就是在这里能对控件属性等等要呈现给用户的数据进行修改,这也是最后的修改,以前的修改(比如在Page_Init里面)都可能被覆盖.做完这了还会进行一个操作就是保存状态,即SaveViewState.

对应的事件时Page.PreRender

 

7. Page_Render();
大家可以在浏缆器里View->Source查看到,每个页面都有一个隐藏的,这里面的"__VIEWSTATE"就是我们服务器写回来的页面状态信息,在这个之前,服务器要呈现页面(也就是构造HTML格式的文件),就是从这个"__VIEWSTATE"里面获取的数据,当然大家也注意到了,这里有个Page.Render事件,我们可以添加自己的处理代码,也就是说我们又可以更改数据,不过这里推荐不要在这里修改,既然提供了PreRender,就应该在里面做最后的修改,当然这不是必须的,只是推荐!

对应的事件Page.Render

 

8. Unload event;
大家应该明白,当想服务器请求一个对象的时候,就会在内存里生成一个继承页面对象,也就是页面的类,它继承自System.Web.UI.Page.
当页面对象从内存中卸载时发生,将触发该事件.

对应的事件Page.Unload

 

9. Dispose method called;
销毁所有的对象.当从内存释放Page时发生,这是生存期的最后阶段。可能第8和9似乎有些模糊,不过我也没怎么搞清楚,待研究!

对应的事件Dispose

以上就是ASP.NET页面周期的描述。

注意上面灰色背景的文字,如果一个过程中有对应的事件,我们可以自己定义一个函数(当然先在MSDN中找到函数原型),然后在
InitializeComponent中向事件的链表上添加上去,像下面:
private void InitializeComponent()
{   
  this.Unload += new System.EventHandler(this.MainWebForm_Unload);
  this.Load += new System.EventHandler(this.Page_Load);
  this.Init += new System.EventHandler(this.Page_Init);
  this.PreRender += new System.EventHandler(this.My_PreRender);
}

对于几个没有对应事件的过程,比如2.Load ViewState,我们可以重载Page的虚函数protected override void LoadViewState(object savedState);来添加自己的控制代码,不过切忌掉用基类的对应方法,比如:
protected override void LoadViewState(object savedState)
{
  //自己处理VIEWSTATE
  base.LoadViewState (savedState);
}

 

页面生命周期详解

深入研究Asp.net页面的生命周期
介绍
Asp.net是微软.Net战略的一个组成部分。它相对以前的Asp有了很大的发展,引入了许多的新机制。本文就Asp.net页面的生命周期向大家做一个初步的介绍,以期能起到指导大家更好、更灵活地操纵Asp.net的作用。
当一个获取网页的请求(可能是通过用户提交完成的,也可能是通过超链接完成的)被发送到Web服务器后,这个页面就会接着运行从创建到处理完成的一系列事件。在我们试图建立Asp.net页面的时候,这个执行周期是不必去考虑的,那样只会自讨苦吃。然而,如果被正确的操纵,一个页面的执行周期将是一道有效而且功能强大的工具。许多开发者在编写Asp.net的页面以及用户控件的时候发现,如果知道整个过程中发生了什么以及在什么时候发生将对完成整个任务起到很重要的帮助作用。下面我就向大家介绍一下一个Asp.net页面从创建到处理完成过程中的十个事件。同时,也向大家展示如何在这些事件中添加自己的代码以达到预定的效果。

 
一.初始化对象
一个页面的控件(以及页面本身)最初应被正确的初始化。通过在你的C#文件的构造函数中声名所有对象(如图1),页面就知道要创建多少对象以及它们的类型。一旦你在你的构造函数中声名了所有的对象,你就可以通过继承类、方法、事件或是属性访问它们。然而,如果你的一些对象是在Aspx文件中指定的一些控件,那么这些控件就没有属性可言了。同时,通过代码访问它们会产生一些意外的错误,因为这些控件实例是没有一个确定的创建顺序的(如果它们是被一起创建的)。还有,你可以通过OnInit来重载初始化事件


二.导入Viewstate数据
在初始化事件后,所有控件只可以通过它们的ID被引用访问(因为还没有相应的DOM可使用)。在LoadViewState这个事件中,所有的控件将获得它们的第一个属性:Viewstate属性。这个属性最终将被返回给服务器以判断这个页面是已经被用户访问完毕还是仍然在被用户所访问。Viewstate属性以“名称/值”对的字符串方式被保存,它包含了控件的文本以及值等信息。该属性被存储在一个隐藏的控件的值属性里,在请求页面时被传递。这种方式比起Asp3.0的维持、判断页面状态的方式有了很大的进步啊。还有,你可以重载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就被保存了。对像的状态数据还是保留在隐藏的控件里面,呈现给Html的对象状态数据也是从这里取得的。在SaveViewState事件中,其值能被保存到viewstate对象,然而这时在页面上控件的修改却不能了。你可以用SaveViewState来重载这一步


九.呈递给Html
运用Html创建给浏览器输出的页面的时候Render事件就发生了。在Render事件过程中,页面调用其中的对象将它们呈递给Html。然后,页面就可以以Html的形式被用户的浏览器访问了。当Render事件被重载时,开发者可以编写自定义的Html代码使得原先生成的Html都无效而按照新的Html来组织页面。Render方法将一个HtmlTextWriter对象作为参数并用它将Html在浏览器上以网页的形式显示。这时仍然可以做一些修改动作,不过它们只是客户端的一些变化而已了。你可以重载Render事件


十.销毁对象
在呈递给Html完成后,所有的对象都应被销毁。在Dispose事件中,你应该销毁所有在建立这个页面时创建的对象。这时,所有的处理已经完毕,所以销毁任何剩下的对象都是不会产生错误的,包括页面对象。你可以重载Dispose事件,见图6。
全文总结
以上就是Asp.net页面生命周期中的十个事件。每次我们请求一个Asp.net页面时,我们都经历着同样的过程:从初始化对象到销毁对象。通过了解Asp.net页面的内部运行机制,我相信大家在编写、调试代码的时候会更加游刃有余的   

 

Http状态码大全

什么是HTTP状态码

简单说;HTTP是一种请求/回应(Request/Response)的网路传输协定,当用户端应用程式(浏览器)要求一网页资讯或资源(Document)时,网站伺服器端就会回传状态码(Status Code),这些状态码通常是以数据化显示,使用者最常见到应该是404,其它包括200、301、302、304、403、410、500等等。

HTTP状态码的英文为HTTP Status Code

下面是常见的HTTP状态码:

200 – 请求成功

301 – 资源(网页等)被永久转移到其它URL

404 – 请求的资源(网页等)不存在

500 – 内部服务器错误

HTTP状态码分类

HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:

HTTP状态码分类

分类

分类描述

1**

信息,服务器收到请求,需要请求者继续执行操作

2**

成功,操作被成功接收并处理

3**

重定向,需要进一步的操作以完成请求

4**

客户端错误,请求包含语法错误或无法完成请求

5**

服务器错误,服务器在处理请求的过程中发生了错误

 

HTTP状态码列表

状态码

状态码英文名称

中文描述

100

Continue

继续。客户端应继续其请求

101

Switching Protocols

切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议

 

200

OK

请求成功。一般用于GET与POST请求

201

Created

已创建。成功请求并创建了新的资源

202

Accepted

已接受。已经接受请求,但未处理完成

203

Non-Authoritative Information

非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本

204

No Content

无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档

205

Reset Content

重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域

206

Partial Content

部分内容。服务器成功处理了部分GET请求

 

300

Multiple Choices

多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择

301

Moved Permanently

永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替

302

Found

临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI

303

See Other

查看其它地址。与301类似。使用GET和POST请求查看

304

Not Modified

未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源

305

Use Proxy

使用代理。所请求的资源必须通过代理访问

306

Unused

已经被废弃的HTTP状态码

307

Temporary Redirect

临时重定向。与302类似。使用GET请求重定向

 

400

Bad Request

客户端请求的语法错误,服务器无法理解

401

Unauthorized

请求要求用户的身份认证

402

Payment Required

保留,将来使用

403

Forbidden

服务器理解请求客户端的请求,但是拒绝执行此请求

404

Not Found

服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置“您所请求的资源无法找到”的个性页面

405

Method Not Allowed

客户端请求中的方法被禁止

406

Not Acceptable

服务器无法根据客户端请求的内容特性完成请求

407

Proxy Authentication Required

请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权

408

Request Time-out

服务器等待客户端发送的请求时间过长,超时

409

Conflict

服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突

410

Gone

客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置

411

Length Required

服务器无法处理客户端发送的不带Content-Length的请求信息

412

Precondition Failed

客户端请求信息的先决条件错误

413

Request Entity Too Large

由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息

414

Request-URI Too Large

请求的URI过长(URI通常为网址),服务器无法处理

415

Unsupported Media Type

服务器无法处理请求附带的媒体格式

416

Requested range not satisfiable

客户端请求的范围无效

417

Expectation Failed

服务器无法满足Expect的请求头信息

 

500

Internal Server Error

服务器内部错误,无法完成请求

501

Not Implemented

服务器不支持请求的功能,无法完成请求

502

Bad Gateway

充当网关或代理的服务器,从远端服务器接收到了一个无效的请求

503

Service Unavailable

由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中

504

Gateway Time-out

充当网关或代理的服务器,未及时从远端服务器获取请求

505

HTTP Version not supported

服务器不支持请求的HTTP协议的版本,无法完成处理

 

session的工作原理
就session的实现而言,好像是这样的:
(1)当有Session启动时,服务器生成一个唯一值,称为Session ID(好像是通过取进程ID的方式取得的)。
(2)然后,服务器开辟一块内存,对应于该Session ID。
(3)服务器再将该Session ID写入浏览器的cookie。
(4)服务气内有一进程,监视所有Session的活动状况,如果有Session超时或是主动关闭,服务器就释放改内存块。                                         

 (5)当浏览器连入IIS时并请求的ASP内用到Session时,IIS就读浏览器Cookie中的Session ID。
(6)然后,服务检查该Session ID所对应的内存是否有效。
(7)如果有效,就读出内存中的值。
(8)如果无效,就建立新的Session

某server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建

2、session何时被删除 

   a.程序调用HttpSession.invalidate();或b.距离上一次收到客户端发送的session id时间间隔超过了session的超时设置;或c.服务器进程被停止(非持久session) 

 

如果服务器发现这是一个新的请求,就会分配给他一个SessionID,也就是在浏览器写入一个sessionID的cookie

Session就丢失是因为我们把Session保存在会话性质的cookie,也就是保存在浏览器的内存中,关闭浏览器时,因为浏览器的内存不存在了,所以session就丢失了。
如果我们能让Session按cookie的第二种存放的方式来实现,那不就可以实现关闭浏览器的时候session不会丢失吗。

 

cookie按照在客户端存放的方式,可以分为两类,
一种是会话性质的cookie,存放在浏览器内存中,当你在用代码向客户端写入cookie的时候,如果没有指定过期时间,那么cookie是存放在浏览器的内存里面的,不会持久化在硬盘上,也就是你在浏览器的临时文件里找不到!
一种是持久化的cookie,存放在硬盘上,当你指定了cookie的过期时间,那么,在客户端写入cookie的时候就会在浏览器的临时文件下生成一个文件,具体格式和名字可以到浏览器临时文件去看下

cookie的原理是这样的:当你在服务器端的代码里写了response.cookie["mycookie"]="mytestcookie"的时候,返回给客户端的http响应中,会在http相应头中加入cookie的信息,浏览器收到相应后,会按照http响应头里的cookie在客户端建立cookie。

//回答ViewState的原理时,说Input版本的TextBox自增和Div版本的Label不同

使用Label进行自增时,Label的值存到了ViewState中,TextBox进行自增时,它的值不用存在ViewState中,禁用ViewState后,textBox版本不受影响,因为textBox就是input,自己会提交给服务器,不需要隐藏字段,而Label版本受影响,因为Label就是Div,值存到了ViewState中

  //asp.net源代码,去除viewstate

        protected LosFormatter losFormatter = new LosFormatter();

        protected override object LoadPageStateFromPersistenceMedium()

        {

            string key = Request.RawUrl + "__viewstate";

            if (Session[key] != null)

            {

                System.IO.MemoryStream stream = (System.IO.MemoryStream)Session[key];

                stream.Seek(0, System.IO.SeekOrigin.Begin);

                return losFormatter.Deserialize(stream);

            }

            return null;

        }

        protected override void SavePageStateToPersistenceMedium(object viewState)

        {

            string key = Request.RawUrl + "__viewstate";

            System.IO.MemoryStream stream = new System.IO.MemoryStream();

            losFormatter.Serialize(stream, viewState);

            stream.Flush();

            Session[key] = stream;

        }

        //EnableEventValidation ="false" 获取或设置一个值,该值指示是否应|当验证回发事件数据。若要验证回发事件数据,则为 true;否则为false,去除EVENTVALIDATION

        //

//value="/wEWAwL+raDpAgLs0bLrBgKM54rGBrUMb5lxucEngd086U57m7FBKiS7qZ3ZRa/WTKXWt6kZ" />

 

Page页面加载顺序

 

初始化(Initialization)

页面被请求时,第一个被执行的总是构造函数(constructor). 你可以在这里初始化很多自定义属性或对象。不过这里有一些限制,因为 page 还没有被完全初始化。特别地,你必须使用 HttpContext.Current 来访问 QueryString, Form, Cookies 集合,以及 Cache 对象。而 Session 对象在 constructor 里是无法访问的。

下面接着执行的是 AddParsedSubObject 方法,这个方法把组成该 page 的所有子控件添加到控件集合树中。在很多高级的页面模板解决方案中,该方法通常被覆盖,以便把页面的控件添加到一个特殊的页面模板中去。该方法递归的被子控件调用,所有这些子控件都是这时候初始化的,从最里面的开始。

接着是 DeterminePostBackMode 方法。该方法允许你影响 IsPostBack 的值,以及相关事件。如果你想从数据库中加载 ViewState 以便 redirect 时,这个可能对你有用。因为 ViewState 仅仅在 IsPostBack 为 true 的时候被恢复。
你可以通过返回 null 来强制不 postback, 或者返回 Request.Form 来强制 postback. 这个方法是不推荐使用的,除非是在特殊的情况下,因为他还影响其他的事件。

然后是 OnInit 方法。通常这是我们使用到的第一个方法。这时,所有控件已经被初始化,也就是说所有原始值都被设定了。而 ViewState 以及所有其他 post 的值还没有被应用到控件上。也就是说这时候所有通过代码或者用户操作做的更改还没有被恢复。这通常是创建或重新创建动态控件的最佳时机。

恢复和加载(Restore and Load)

接下来的 LoadPageStateFromPersistenceMedium 方法,仅仅在 PostBack 时被执行。当你要改变保存 ViewState 的方法时(使用 Session 或其他自定义的储存方法),覆盖这个方法,以及后面的 SavePageStateToPersistenceMedium 方法。注意:该方法并不真正加载 ViewState 到 page 及其子控件。

ViewState 被取回后,接着 LoadViewState 方法将它们恢复到 page,并递归的恢复到每一个子控件(只有 PostBack 的那些).这时,每个控件已经被恢复到了它上次执行时的状态,但用户 post 的值还没有被应用。因为这属于 ViewState. 这个方法是恢复所有在事件中创建的动态控件的最好时机。

下一个是 ProcessPostData 方法。仅仅在 PostBack 时被执行。而且这个方法不能被覆盖,因为它是页面基类中实现的一个私有方法。这个方法最终将用户 post 的值,通过匹配控件的名称的方法,恢复到页面。这时,page 已经被完全恢复了。动态控件必须在这个方法之前被创建。这个方法同时也为稍后的 changed 事件记录控件值的改变。

然后才是 OnLoad 方法。大部分的代码中都使用这个方法,因为这是在 page 的生命周期中,第一个所有的值都被恢复了的地方。我们可以通过检查 IsPostBack 属性来避免不必要的重设状态。同时也可以检查 IsValid 属性来进行验证。同时还可以在这里创建动态控件。所有这些控件的方法都会被执行并捕获,包括 ViewState. 但回发的值不可以。

Raised Events

下一个方法,ProcessPostData 方法,实际上是前面那个方法的第二个入口(second pass)。它仅仅处理回发,而且由于是私有方法,所以不能被覆盖。这个方法显得有些奇怪,但又是必要的。因为在 OnLoad 方法中重建的动态控件需要他们回发的值。所有在这个方法之后创建的动态控件,将只能恢复 ViewState, 而不能恢复回发的值,并且不能触发任何更改事件。

下一个方法, RaiseChangedEvents,同样仅仅用于回发时。它是一个基类实现的私有方法。这时 changed 事件被真正触发。这基于前面 ProcessPostData 方法中标注出回发的值的差异。当有多个 changed 事件被触发时,其先后顺序是没有保证的。

下面是 RaisePostBackEvent 方法。仅用于回发,而且是基类实现的私有方法。这是真正提交 form 的方法,除非是 postback。比如按钮,或者其他通过 javascript 提交的控件被触发。如果使用了 Validators, 如没有手动调用 Validate 方法,这时也已经被调用了。有时候 ie 的 bug 会使得表单被提交,而不引发事件。

接着是 OnPreRender 方法。这通常是在被绘制到浏览器之前,要更改 page 及其子控件的最后机会。你也可以在这里创建动态控件。但这时只能捕获 ViewState, 而不能接受 posted values, 而且没有事件。因为上面提到的 ie 的 bug, 这里可以用来捕获没有触发事件的 post back.

保存和绘制(Save and Render)

下一个是 SaveViewState 方法。 不管是否 post back. 递归的应用到每一个子控件。ViewState 一般保存所有和 aspx 页面里不一样的属性,不管是被代码还是用户更改的。注意,由于控件的值是通过他们在控件树中的位置来保存的,所以如果在这之后添加动态控件到错误的位置, ViewState 可能会崩溃。

下面是 SavePageStateToPersistenceMedium 方法。它真正的保存 page 的 ViewState. 这个方法可覆盖。如果重写的话,注意这里由于 asp.net 的 bug, 需要手工设定一下 __VIEWSTATE,哪怕是空值。

接着是 Render 方法。它递归的调用到每个子控件,真正的绘制各自的 html, 发送到浏览器。在一些页面模板方案中,常常在这里添加通用的 header 和 footer. 而不用使用服务器控件。 注意在这里能作的更改必须是纯的 html. 因为这时候控件都已经绘制完了。

最后是 OnUnload 方法。它调用了 Dispose 方法。这个方法可以用来清理页面中使用的非托管资源。特别是类似于关闭打开的文件或数据库连接等。该方法只有当页面已经被发送到客户端浏览器后才发生。所以它只能对服务端的对象起作用。所以他不能在 page 的 trace 中被显示。

上面就是 page 的生命循环。每次有一个新的请求时,以上过程就重复一次。

Listing 1: Page 的事件小结

 

Method

PostBack

Controls

Constructor

Always

All

AddParsedSubObject

Always

All

DeterminePostBackMode

Always

Page

OnInit

Always

All


LoadPageStateFromPersistenceMedium

PostBack

Page

LoadViewState

PostBack

All

ProcessPostData1

PostBack

Page

OnLoad

Always

All


ProcessPostData2

PostBack

Page

RaiseChangedEvents

PostBack

Page

RaisePostBackEvent

PostBack

Page

OnPreRender

Always

All


SaveViewState

Always

All

SavePageStateToPersistenceMedium

Always

Page

Render

Always

All

OnUnload

Always

All


1.    Master page中的用户控件的 page_init
2.    Aspx页面中的用户控件的 page_init
3.    Master page的page_init
4.    Aspx的 page_init
5.    Aspx的page_load
6.    Master page的page_load
7.    Master page中的用户控件的 page_load
8.    Aspx页面中的用户控件的 page_load

.aspx、.master、ascx这三个页面中Page_Load的执行顺序是:.aspx中的page_load -->.master中的page_load -->ascx中的page_load

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值