关于冗余和viewstate

来源:互联网 发布:社交网络头像 编辑:程序博客网 时间:2024/05/19 02:20


冗余:百度百科解释多余的、重复或者啰嗦内容(包括信息、语言、代码等)


<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="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" />
这个是所有服务器控件的上一次属性值的Byse64String编码过的字符串,只要是使用了服务器控件就避免不了。(产生的这个东西顶多叫垃圾而已,不是冗余)
在PreRender事件的处理程序中,会把所有服务器控件的属性值序列化为字符串,输出到_viewstate中

ASP.NET中的ViewState

ViewState是ASP.NET中用来保存WEB控件回传时状态值一种机制。在WEB窗体(FORM)的设置为runat="server",这个窗体(FORM)会被附加一个隐藏的属性_VIEWSTATE。_VIEWSTATE中存放了所有控件在ViewState中的状态值。

ASP.NET中,为了模拟Winform中的事件响应机制,微软的工程师真是煞费苦心,发明了“回发”机制,使得编写WEB页面变得和Winform一样简单。


所谓回发机制,其实说白了就是自己发送给自己(本页面)而已。下面我们新建一个网站,打开默认添加的Default.aspx页面,form部分代码如下: 

<form id="form1" runat="server" > <div> </div> </form> 

下面是运行页面后的HTML代码:
<form name="form1" method="post" action="Default.aspx" id="form1"> <div> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGSWiVUOl9W4QUXb+tXv2k5s4yXFog==" /> </div> <div> </div> </form> 

我们可以看到原本空荡荡的form表单内变得丰富起来,首先发生变化的就是form表单自身,<form id="form1" runat="server" >被解释成了<form name="form1" method="post" action="Default.aspx" id="form1">,自动的给form1这个表单增加了action和method属性,method默认为post,action则指向页面本身。另外一个发生变化的就是form1表单中增加了一个id="__VIEWSTATE" 的隐藏域,这就是我们要讨论的ViewState 
  我们再举一个例子:这时,我们向页面中添加一个Label一个TextBox还有一个Button代码如下: 
<form id="form1" runat="server" > <div> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br /> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br /> <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click"/> </div> </form> 
然后在Button1_Click中写如下代码: 
protected void Button1_Click(object sender, EventArgs e) { Label1.Text += "你好"; TextBox1.Text += "你好"; } 

好了,现在我们来给Button1增加一些点击量,可以看到,Label控件和TextBox控件随着我们点击量的提高,其内容也在不断的变化,这种情况在Winform中非常常见,也很容易理解,可是ASP.NET是基于HTTP协议的,而HTTP协议是无状态协议。也就是说,服务器有健忘症,明明不久前刚刚给他发出过请求,创建了一个page对象,并做出响应。但是第二次请求到达的时候,服务器已经不认识你了(服务器会创建一个全新的page对象,和之前那个没有任何关系,再次给出响应)。在这种服务器有健忘症的恶劣条件下,要达到Winform一样的效果,真不是一件简单的事情。 
  我们给预编译指令Page增加一个属性EnableViewState="false"(禁用ViewState)之后,再重新运行页面,继续连续点击Button1,看这下是什么效果?大家会发现Label控件效果没有变化,但是TextBox控件内容却还在继续发生着变化。这是什么原因呢?其实我们只要查看一下源代码就会发现: 

<div> <span id="Span1">Label</span><br /> <input name="TextBox1" type="text" id="Text1" /><br /> <input type="submit" name="Button1" value="Button" id="Submit1" /> </div> 

3个控件分别变成了span,文本框(text)和提交按钮(submit),当我们点击Button1时HTML会将要提交的表单中的所有表单控件的name和value属性用“&”连接成name=value的字符串,然后向action指向的页面,method指定的方式,发送请求。我们可以将<form id="form1" runat="server" >表单的发送方式修改为get(<form id="form1" runat="server" method="get">)再点击提交,就可以注意到地址栏的变化了。 
  由于Label控件最终生成的标签是span,但是表单在提交时,不会提交span标签中的value,但是却会提交input中的value,所以服务器可以得到input最新的value,而由于没有发送span的value,所以服务器无法得到span最新的修改。这就是为什么当禁用ViewState时,Label不会变化,而input还是会发生变化的原因了。要解决这个问题,asp.net引入了ViewState,其实ViewState就是一个hidden隐藏域而已。表单不会发送span标记的value但是却会发送hidden控件的value,于是asp.net在给span标记赋值的时候,再给这个名叫ViewState的hidden控件记录一份,这样服务器就可以从hidden中获得Label标签原来的内容了。 
  这就是ViewState的本质,当然在服务器端还有LoadViewState和SaveViewState方法。



0 0
原创粉丝点击