ASP.NET的页面生存周期和ViewState实现机制

一、定义

页面生存周期 是指 一个ASP.NET页面类型对象从初始化到销毁经过的步骤。

一旦某个请求对应到一个ASP.NET页面时,一个直接或间接继承自 System.Web.UI.Page 类型的对象会开始初始化

并且开始执行页面生存周期中的所有步骤。

这个对象就是客户端请求的ASP.NET页面的后台托管代码

可在页面<%@ page /%>指令中加Trace属性

PreInit Init InitComplete

LoadState ProcessPostDate PreLoad Load ProcessPostData

ChangedEvents PostBackEvent

SaveState SaveStateComplete Render

二、各步骤的功能

1).初始化

PriInit、Init和 InitComplete

功能: 初始化类对象、初始化主题主页面、判断是否是第一次访问等

2).加载数据和页面

LoadState、ProcessPostDate、PreLoad、Load、ProcessPostData(第二次)等

首先从页面回传的数据加载 ViewState对象, 所有的数据以 Base64 编码随页面传入服务器

然后开始处理回传的数据,也就是把表单中的 键/值 对存入对象之中

随后开始加载页面,程序员通常会在这里做一些初始化的编程,例如 OnLoad事件中编写页面初始化代码

最后再次执行ProcessPostData,以处理Load时新添加的数据。

3).触发事件

包含了 ChangedEvents 和 PostBackEvent步骤。

首先比较 ViewState 中的数据 和 页面上一次回传的数据,以发现有哪些事件需要被触发,这里事件是被逐一触发

的,其顺序无法确定

4).保存状态并呈现页面

SaveState SaveStateComplete Render步骤

首先,页面会编码保存所有的 ViewState数据

然后,将其嵌入到页面的一个隐藏控件中

接着,转换所有的控件标签并生成页面HTML,并且发送回客户端

三、ViewState机制

1).概述

ASP.NET 服务器控件 从 System.Web.UI.Control(定义由所有 ASP.NET 服务器控件共享的属性、方法和事件) 继承名为 ViewState只读属性,使之加入了状态管理机制。利用之获取状态信息的字典,这些信息使您可以在同一页的多个请求间保存和还原服务器控件的视图状态 ViewState的类型是 System.Web.UI.StateBag, 它是 存储 键/值 对的字典。

2).ViewState的实现机制

简单来说,每次服务器发送给客户端的页面中都隐藏了一个数据,该数据用以保存ViewState。当客户端再次提交表单时,ViewState就会又随这表单一起提交到服务器端,循环往复就达到了持续保存数据的功能。

步骤

客户申请一个新的带有 ViewState 字段的页面,第一次申请时 ViewState字段内数据为空

客户提交表单,ViewState字段作为表单的一部分被提交,此时为空

服务器从表单中读取 ViewState的数据,解码解密,并且存入 ViewState 对象中,第一次仍然为空

服务器处理完表单数据后,把表单数据相应写入 ViewState 对象,这时 ViewState对象就有值了

服务器把 ViewState 对象加密并编码,然后写入页面的 ViewState 字段。 此时页面 ViewState 字段就包含了

上次提交的表单内的控件数据和服务器代码写入ViewState的数据

服务器把页面发还给客户端,客户端得到了 ViewState数据

因为 Page类继承自 TemplateControl类,而TemplateControl类又继承自 Control类,故可以直接使用 ViewState属性。

这一功能在关闭 控件的 ViewState之后 极其有用。

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

public partial class _Handler:System.Web.UI.Page;
{
    protected void Page_Load(Object sender, EventArgs e)
    {
        if(!Page.IsPostBack)
        {
            //初始化Value值
            ViewState["VALUE"]=0;
            Output();
        }
    }
    
    protected void GO_Click(object sender, EventArgs e)
    {
        //使Value值自增1
        ViewState["VALUE"]=(int)ViewState["VALUE"]+1;
        Output();
    }
    
    private void Output()
    {
        //呈现  OUTPUT为页面的asp:Label控件
        Output.Text=ViewState["VALUE"].ToString();
    }
}

3). 实质

asp:Label 控件 实质是System.Web.UI.WebControls.WebControl.Label 它是一个类。由于 WebControl 类继承自

System.Web.UI.Control类,而 Control 类拥有 ViewState 属性。 故实质为 使用 ViewState 机制的类。

查看返回页面的源代码一般看到类似如下的一个input

其中 value值 使用 BASE64编码的。 value值 实质为XML文件,保存了 所有了 ViewState对象。

<input type=”hidden” name=”_EVENTVALIDATION” id=”_EVENTVALIDATION” value=”/wEWAgK+heeOALZ767wDFMnBmL0VTVt5dZTfeWG6RrWb7b7jc”/>

而 asp:Textbox 控件 则是直接 实现 <input type=”hidden” /> 机制,不受 ViewState机制影响