视图状态是 ASP.NET 页面中的一个仓库,用来存储需要在回传过程期间被保持的状态值。视图状态通常胜于会话数据或用户数据而被用于存储必须被保持的页面变量。例如,在页面下一次被发送到服务器的时候,你能够在载入事件期间把将要被访问的信息存储到视图状态中。关于使用建议,请参考:[ASP.NET 状态管理的建议]。
视图状态是基于 64 位编码的字符串,并且被存储在页面的若干隐藏字段中。你能够使用页面的 ViewState
属性来访问视图状态信息,该属性暴露了一个字典对象。因为视图状态中的数据是被当作字符串进行存储的,所以只有能够被序列化的对象才能被存储到视图状态中。
在视图状态当作隐藏字段被发送以后,视图状态才能够在 PreRenderComplete
事件中被更改。一旦页面在浏览器中被呈现,对视图状态的更改将不再被保存。
如果页面的输出源被查看到,那么隐藏在视图状态字段中的信息也同样会被查看到,从而引起了一个潜在的安全问题。要缓解这个问题,你可以在 @ Page
指令中把 viewStateEncryptionMode
参数设置成 Always
。关于在视图状态中保存信息的安全问题的更多信息,请参考:[保护视图状态]。
提示:要使用 ViewState
属性,ASP.NET Web 页面必须拥有一个服务器窗体元素(<form runat="server">
)。关于使用建议,请参考:[ASP.NET 状态管理的建议]。
该实例在视图状态中保存了一个字符串和一个整数值。
在视图状态中保存值
-
在页面的代码中,设置
ViewState
属性中的变量值。如下代码实例说明了如何把一个
ArrayList
对象保存到视图状态中。<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> // 页面中的实例 ArrayList。 ArrayList PageArrayList; ArrayList CreateArray() { // 创建一个实例 sample ArrayList。 ArrayList result = new ArrayList(4); result.Add("item 1"); result.Add("item 2"); result.Add("item 3"); result.Add("item 4"); return result; } void Page_Load(object sender, EventArgs e) { if (ViewState["arrayListInViewState"] != null) { PageArrayList = (ArrayList)ViewState["arrayListInViewState"]; } else { // ArrayList 没有在视图状态中,所以我们需要从对它进行手动载入。 PageArrayList = CreateArray(); } // 使用 PageArrayList 的代码。 } void Page_PreRender(object sender, EventArgs e) { // 在页面被呈现之前保存 PageArrayList。 ViewState.Add("arrayListInViewState", PageArrayList); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>View state sample</title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
加密视图状态
-
在
@ Page
指令中,把ViewStateEncryptionMode
参数设置成Always
,如下实例所示:<% @Page ViewStateEncryptionMode="Always" ... %>
健壮编程
只有被标记为 Serializable
的类型才能够被存储到视图状态中。关于更多信息,请参考:[视图状态概览]。
被存储的视图状态信息使用了基于 64 位的编码,并且在呈现期间被包括在页面中,从而增加了页面的尺寸。在页面被回传的时候,视图状态会作为页面回传信息的一部分而被发送。因为视图状态能够严重地增加网络流量并减慢网络连接的速度,所以建议你不要在视图状态中存储庞大的信息量。
另一个重要的考虑就是一旦页面中隐藏字段的数据量变得庞大,有些代理和防火墙将会限制对这些页面的访问。这是因为对于隐藏字段中数据量的限制能够随着不同的防火墙和代理的实现而变化,庞大的隐藏字段能够引起不可预知的行为。关于更多信息,请参考:[ASP.NET 状态管理的建议]。
有些移动设备不允许使用任何隐藏字段。因此,视图状态将无法在这些设备中运作。关于更多信息,请参考:[理解状态管理]。
安全
视图状态中的信息基于 64 位格式的编码,但是它能够被恶意用户所篡改。你应该把被存储在视图状态中的信息当成用户所提供的数据一样来对待并始终在使用之前进行验证。关于缓解视图状态安全风险的更多信息,请参考:[保护视图状态]。关于保护 ASP.NET 应用程序的常规信息,请参考:[保护 ASP.NET Web 应用程序和 Web 应用程序的基本安全练习]。