小弟开始系统性的学习ASP.NET了,刚学到View State感觉书上说的有点模糊,于是小弟查了些资料,终于对这个东东有一个大概了解,
我想也是时候总结下了,同时也跟入门的小伙伴分享下心得,废话不多说Go
我们都知道当点击按钮或者刷新网页的时候,会导致向服务器执行一个回发动作,然后服务器再重新加载回送页面信息,我们也知道http协议是无状态的
无状态的通俗的理解是:每次服务器加载的都是初始的页面信息,即你把一个Asp.net的 label控件文本更改了,当你重新刷新页面的时候,服务器加载回送的页面信息还是初始的文本即(label1)
常见的解决办法是可以通过手动编写代码,在服务器加载回送页面后预先填充控件来实现这一功能,幸运的是,ASP.NET将这个功能集成到了功能集中即View State,因此无需我们自己手动编写代码,但是必须要了解View State实现机制,因为它的开销非常大,如何关闭请自己搜索,现在先让我们了解下View State如何实现的。
当在页面上拖一个label控件和一个button控件
页面代码如下
<body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br /> <br /> <asp:Button Text="button" value="button" runat="server" OnClick="Button_Click" /> </div> </form> </body>
在button的点击事件处理器里添加CS代码如下
protected void Button_Click(object sender, EventArgs e) { this.Label1.Text = "ChangedText"; }
F5运行然后打开查看浏览器的源代码可以看见我们页面的源代码(如下)
<form method="post" action="WebForm1.aspx" id="form1"> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="qJK68X0jGyjxASf74eN78QeV0E8KvfKVs7YHm84yCePKKNlMrAv04sfWyTh06hsdBxM3fQdv1zQUyG1+WV1BH9SL6Y2gaIuIP1x0PMfVCqw=" /> <div> <span id="Label1">Label</span><br /> <br /> <input type="submit" name="ctl03" value="button" value="button" /> </div> </form>
这生成代码看起很抓狂
Html <from>元素用于让用户从浏览器向服务器提交信息,用户可以用一些控件来输入信息只要是表单的元素它们的值都会被提交。
细心的朋友看见了我们添加的Label控件被生成了span标签元素,这是因为ASP.NET所有的服务器控件最终都会被ASP.NET运行库翻译成html代码
而span标签不属于from表单元素,所以它的值不会被提交给服务器,即你把label文本改成其它信息也不会被提交,那ASP.NET运行库是如何保存我们的值的呢?
再看下源码你会发现from表单元素多了hidden元素 (如下)
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="qJK68X0jGyjxASf74eN78QeV0E8KvfKVs7YHm84yCePKKNlMrAv04sfWyTh06hsdBxM3fQdv1zQUyG1+WV1BH9SL6Y2gaIuIP1x0PMfVCqw=" />
虽然hidden元素的Value除了一些随机字符外都看不懂,但是是它实际包含了有用的信息,如果解析下就会发现是我们label文本的值
所以当我们第一次请求页面时,ASP运行库会用label的Text的信息填充这个hidden元素,然后加载成功后我们页面信息就是
label.Text=label1
hidden.value=label1
然后当我们点击按钮时会执行一个回发,hidden的值会被回发到服务器,此时的hidden的value还是label
并未改变,因为我们用的是后台代码,在执行到后台代码时即this.label.text="ChangedText" ASP运行库会把hidden的Value变成ChangedText
此时该页面会被再次构建并设置所有默认值,这也意味着label的Text还是label1,然而之后不久在同一个处理周期中运行库会把提交回的hidden的Value(ChangedText)重新指派给Label的Text,所以当我们刷新或改变label值的时候始终能保持状态。
需要了解的是并不是所有控件都依赖于ViewState,有很多控件能维持它们自己的状态,这些控件包括 TextBox、CheckBox、RadioButton、DropDownList等。