您的位置:首页 > 编程语言 > ASP

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

2010-01-28 20:35 531 查看
[b]Asp.Net 中引入ViewState的背景:[/b]

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

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

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

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

[b]ViewState 保留页值的方法:[/b]

先看初始状态下,所建立服务器端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 }
if (IsPostBack)
{
//在回送状态下,实现ViewState的逐个累加
ViewState["count"] = (int)ViewState["count"] + 1;
}

}
protected void btnSub1_Click(object sender, EventArgs e)
{
//旨在通过点击btnSub1触发事件,实现将ViewState状态值,及时反馈在lbelDemo中
lbelDemo.Text = ViewState["count"].ToString();
}
}在浏览器上,初次展现为(如下图):

代码<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"],这样的键/值,实现了在页面的往复间依然保留页值的功能。

[b]ViewState 保留控件值的方法:[/b]

在这里采用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 所采用的视图状态管理,极大地改进了性能。本文仅就其两类使用方法稍加概述,呵呵
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: