Asp.Net 中ViewState—视图状态浅析

Asp.Net 中引入ViewState的背景:

       由于Http请求是一种无状态请求,即Web服务器不会记录任何客户端的独特信息,以最大效率的运行。然而此时(假设是用纯Asp 语言),假若我们提交了文本框至服务器,在提交过程中,从服务器端重新返回实例化一个页面类的对象,而这个对象页并没有保留住我们之前输入文本框的值,即我们的值丢失了!

       正是在上述背景下,作为Asp 与 .NET框架的完美结合体——Asp.Net 产生了。为了克服这种障碍,其引入的状态管理功能,即应用ViewState可以在同一页面的多次服务器请求之间保留以及控件的值,成功克服了这种困难!

       在默认情况,Asp.Net页框架使用ViewState在多次回送之间保留控件值,而在发送至客户端浏览器的HTML代码上,则具体表现为一个或多个隐藏的<input type="Hidden">字段。

      下面即就ViewState 所针对的两种保存值对象——页值控件值,分而讨论之:

 

ViewState 保留页值的方法:

先看初始状态下,所建立服务器端HTML代码:

<form id="form1" runat="server">
    
<div>
        
<asp:Label ID="lbelDemo" runat="server" Text="lbelInit"></asp:Label>
        
<br />
        
<asp:Button ID="btnSub1" runat="server" Text="btnSub1" 
            onclick
="btnSub1_Click" />
        
<asp:Button ID="btnSub2" runat="server" Text="btnSub2" />
    
</div>
    
</form>

其对应的后台代码为:

 1 public partial class _Default : System.Web.UI.Page 
 2 {
 3     protected void Page_Load(object sender, EventArgs e)
 4     {
 5         if (!IsPostBack)
 6         {
 7             //赋予ViewState为整数int型,初值为1
 8             ViewState["count"= 1;
 9         }
10         if (IsPostBack)
11         {
12             //在回送状态下,实现ViewState的逐个累加
13             ViewState["count"= (int)ViewState["count"+ 1;
14         }
15 
16     }
17     protected void btnSub1_Click(object sender, EventArgs e)
18     {
19         //旨在通过点击btnSub1触发事件,实现将ViewState状态值,及时反馈在lbelDemo中
20         lbelDemo.Text = ViewState["count"].ToString();
21     }
22 }

在浏览器上,初次展现为(如下图):

 

查看其源代码为:

代码
<body>
    
<form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTExNjMzNDIxNjQPFgIeBWNvdW50AgFkZD/xqNtuWCI2N3knwGlV+hqR7lUO" />
</div>

<div>

    
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwKRvOPFDgKU2NnBCwKvwffWBd/L4HJDqcil+WEelebQudVq4Brk" />

</div>
    
<div>
        
<span id="lbelDemo">lbelInit</span>
        
<br />
        
<input type="submit" name="btnSub1" value="btnSub1" id="btnSub1" />
        
<input type="submit" name="btnSub2" value="btnSub2" id="btnSub2" />
    
</div>
    
</form>
</body>

此时可见,在源代码中已经维持了一个隐藏的、用于保存值的字段,代码为:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTExNjMzNDIxNjQPFgIeBWNvdW50AgFkZD/xqNtuWCI2N3knwGlV+hqR7lUO" />

通过这个隐藏字段(其实质为本部分讨论的页值保存,以及马上讲的控件值保存项),即可以实现页值,在这里即ViewState["count"]保存,在这里可以通过btnSub1的触发事件实现,见下图,可见lbelDemo的值随点击次数逐次累加:

 

 

这样通过在页面级别的ViewState["count"],这样的键/值,实现了在页面的往复间依然保留页值的功能。

 

ViewState 保留控件值的方法:

      在这里采用Label这样一个比较特殊的服务器端控件(因为在HTML 中并不具备Label控件,这就依赖于.NET 的CLR实现将Label 转化为Span ,从而实现解析的目的)。

     依然采用上述的例子,做一些改动:

     初始状态下的,服务器端代码不变,为:

<form id="form1" runat="server">
    
<div>
        
<asp:Label ID="lbelDemo" runat="server" Text="lbelInit"></asp:Label>
        
<br />
        
<asp:Button ID="btnSub1" runat="server" Text="btnSub1" 
            onclick
="btnSub1_Click" />
        
<asp:Button ID="btnSub2" runat="server" Text="btnSub2"

           onclick="btnSub2_Click"/>

 而其对应后台代码,做了较大改动,代码为:

public partial class _Default : System.Web.UI.Page 
{
    
protected void Page_Load(object sender, EventArgs e)
    {
       

    }
    
protected void btnSub1_Click(object sender, EventArgs e)
    {

        lbelDemo.Text 
= "Label Text has been Changed";
    }
    
protected void btnSub2_Click(object sender, EventArgs e)
    {

    }
}

这样在初始页面、点击btnSub1、点击btnSub2之后页面的状态图示,如下:

 

 

 

 可以看到初始状态同页值初始状态,而点击btnSub1和btnSub2之后,页面显示相同,这就是因为:点击btnSub1之后,后台CLR运营的ViewState更新了lbelDemo属性的变化,并及时更新,同时反馈、显示在客户端HTML中。当btnSub2点击后,由上一篇文章《Asp.Net 生命周期浅析》中已经介绍页面的加载顺序了,在此不再鳌述,ViewState值加载进lbelDemo,从而实现控件值保留。

这样就实现了ViewState保留控件值的目的。

 

附:

1.对于利用ViewState保留控件值的方法,要依赖于所有控件都具有的属性——EnableViewState的True 或 False。ex,在Label控件中将其属性ViewState设置为false后,展示的三个页面为:

 

可见点击btnSub2之后,展示的是初始lbelDemo的Text值,这是因为"禁用"控件ViewState属性所致;

2. 对于利用ViewState保留控件值的方法。当对于TextBox等控件时,即使EnableViewState设置为false,照样可以实现保留功能,原因就在于其本身携带其属性值,这在初始化页面时已经加载了!所以ViewState并不是对所有服务器端控件都是必须的;

3.对于隐藏的ViewState字段,如果携带大量数据,将降低数据传输效率(而且好像有最大量限制。),可以考虑禁用一些控件的ViewState属性,然这不是本文着重,不鳌述。

 

综论之,Asp.Net 所采用的视图状态管理,极大地改进了性能。本文仅就其两类使用方法稍加概述,呵呵

 

 

 

 

       

posted @ 2010-01-28 20:35  Youngman  阅读(1576)  评论(2编辑  收藏  举报