在编程中也可以使用viewstate来存放数据。
例如
在ViewState存放数据:
ViewState[key] = value;
或
ViewState.Add(key, value);
取出数据:
TempStr = ViewState[key];
key不存在时返回空。
不能通过ViewState对象来访问控件的值。
- 如果要使用 ViewState,则在 ASPX 页面中必须有一个服务器端窗体标记 (<form runat=server>)。窗体字段是必需的,这样包含 ViewState 信息的隐藏字段才能回传给服务器。而且,该窗体还必须是服务器端的窗体,这样在服务器上执行该页面时,ASP.NET 页面框架才能添加隐藏的字段。
- 页面本身将 20 字节左右的信息保存在 ViewState 中,用于在回传时将 PostBack 数据和 ViewState 值分发给正确的控件。因此,即使该页面或应用程序禁用了 ViewState,仍可以在 ViewState 中看到少量的剩余字节。
- 在页面不回传的情况下,可以通过省略服务器端的 <form> 标记来去除页面中的 ViewState。
' 保存在 ViewState 中ViewState("SortOrder") = "DESC"' 从 ViewState 中读取Dim SortOrder As String = CStr(ViewState("SortOrder"))// 保存在 ViewState 中ViewState["SortOrder"] = "DESC";// 从 ViewState 中读取string sortOrder = (string)ViewState["SortOrder"];
<%@ Import Namespace="System.Data" %><HTML><HEAD><title>用于页面 UI 状态值的 ViewState/title></HEAD><body><form runat="server"><H3>在 ViewState 中存储非控件状态</H3><P>此示例将一列静态数据的当前排序顺序存储在 ViewState 中。<br>单击列标题中的链接,可按该字段排序数据。<br>再次单击该链接,将按相反顺序排序。<br><br><br><asp:datagrid End If' 绑定网格DataGrid1.DataSource = dvDataGrid1.DataBind()End SubPrivate Sub SortGrid(sender As Object, e As DataGridSortCommandEventArgs)DataGrid1.CurrentPageIndex = 0SortField = e.SortExpressionBindGrid()End Sub</script>
<%@ Page Language="C#" %><%@ Import Namespace="System.Data" %><HTML><HEAD><title>用于页面 UI 状态值的 ViewState</title></HEAD><body><form runat="server"><H3>在 ViewState 中存储非控件状态</H3><P>此示例将一列静态数据的当前排序顺序存储在 ViewState 中。<br>单击列标题中的链接,可按该字段排序数据。<br>再次单击该链接,将按相反顺序排序。<br><br><br><asp:datagrid ;}// 绑定网格DataGrid1.DataSource = dv;DataGrid1.DataBind();}void SortGrid(object sender, DataGridSortCommandEventArgs e) {DataGrid1.CurrentPageIndex = 0;SortField = e.SortExpression;BindGrid();}</script><?xml version="1.0" standalone="yes"?><NewDataSet><Table><pub_id>0736</pub_id><pub_name>New Moon Books</pub_name><city>Boston</city><state>MA</state><country>USA</country></Table><Table><pub_id>0877</pub_id><pub_name>Binnet & Hardley</pub_name><city>Washington</city><state>DC</state><country>USA</country></Table><Table><pub_id>1389</pub_id><pub_name>Algodata Infosystems</pub_name><city>Berkeley</city><state>CA</state><country>USA</country></Table><Table><pub_id>1622</pub_id><pub_name>Five Lakes Publishing</pub_name><city>Chicago</city><state>IL</state><country>USA</country></Table><Table><pub_id>1756</pub_id><pub_name>Ramona Publishers</pub_name><city>Dallas</city><state>TX</state><country>USA</country></Table><Table><pub_id>9901</pub_id><pub_name>GGG&G</pub_name><city>Muenchen</city><country>Germany</country></Table><Table><pub_id>9952</pub_id><pub_name>Scootney Books</pub_name><city>New York</city><state>NY</state><country>USA</country></Table><Table><pub_id>9999</pub_id><pub_name>Lucerne Publishing</pub_name><city>Paris</city><country>France</country></Table></NewDataSet>
- 大量的数据。由于 ViewState 增加了发送到浏览器的页面的大小(HTML 有效负载),同时也增加了回传的窗体的大小,因此不适合存储大量数据。
- 未在 UI 中显示的安全数据。尽管 ViewState 数据已被编码,并且可以选择对其进行加密,但始终不将数据发送到客户端才是最安全的。因此,会话是更安全的选择。(由于数据库需要额外的凭据进行验证,因此将数据存储在数据库中会更安全。可以添加 SSL 以获得更安全的链接。)但是,如果在 UI 中已经显示了该专用数据,那么您应该已经确认了链接的安全性。在这种情况下,将同样的值放入 ViewState 不会降低安全性。
- 尚未序列化到 ViewState 中的对象,如 DataSet。ViewState 序列化程序只为一小部分常用的对象类型进行了优化,如下所示。其他可序列化的类型或许可以保留在 ViewState 中,但速度会变慢,并会生成一个非常大的 ViewState。
- 在不需要时禁用 ViewState。下面的“减少使用 ViewState”一节将详细介绍这一问题。
- 使用优化过的 ViewState 序列化程序。上面列出的类型具有专门的序列化程序,这些程序运行速度很快,并已经过优化,可以生成很小的 ViewState。如果要序列化一个未在上面列出的类型,可以创建一个自定义 TypeConverter 来显著提高它的性能。
- 尽量减少使用对象,如果可能,尽量减少放入 ViewState 中的对象的数目。例如,不要使用二维字符串数组(名称/值,其对象的数目与数组的长度一样多),而应使用两个字符串数组(只有两个对象)。但是,在将两个已知类型存储在 ViewState 中之前,在这两者之间转换不会获得任何性能提高,因为这样做实际上相当于付出了两次转换的代价。
- 页面不回传给自身。
- 处理的不是控件的事件。
- 控件没有动态的或数据绑定的属性值(或对于每一个请求它们都设置在代码中)。
<%@ Import Namespace="System.Data" %><html><body><form runat="server"><asp:DataGrid runat="server" /></form></body></html><script runat="server">Private Sub Page_Load(sender As Object, e As EventArgs)Dim ds as New DataSet()ds.ReadXml(Server.MapPath("TestData.xml"))DataGrid1.DataSource = dsDataGrid1.DataBind()End Sub</script><HTML><HEAD><title>减少页面的“HTML 有效负载”</title></HEAD><body><form name="_ctl0" method="post" action="lessviewstate.aspx" />
<HTML><HEAD><title>减少页面的“HTML 有效负载”</title></HEAD><body><form name="_ctl0" method="post" action="lessviewstate.aspx" />
<%@ Import Namespace="System.Data" %><html><HEAD><title>减少页面的“HTML 有效负载”</title></HEAD><body><form runat="server"><H3>通过禁用 ViewState 来减少页面的“HTML 有效负载”</H3><P><asp:datagrid ))DataGrid1.DataSource = dsDataGrid1.DataBind()End Sub</script>
<%@ Page Language="C#" %><%@ Import Namespace="System.Data" %><html><HEAD><title>减少页面的“HTML 有效负载”</title></HEAD><body><form runat="server"><H3>通过禁用 ViewState 来减少页面的“HTML 有效负载”</H3><P><asp:datagrid ));DataGrid1.DataSource = ds;DataGrid1.DataBind();}</script>
- 防篡改
- 加密
<%@Page EnableViewStateMAC=true %>
<machineKey validation="MD5" />
<machineKey validation="3DES" />
<machineKey validation="SHA1" validationKey="F3690E7A3143C185AB1089616A8B4D81FD55DD7A69EEAA3B32A6AE813ECEECD28DEA66A23BEE42193729BD48595EBAFE2C2E765BE77E006330BC3B1392D7C73F" />
<%@ Page Language="c#" %><%@ Import Namespace="System.Security.Cryptography" %><HTML><body><form runat="server"><H3>生成随机加密密钥</H3><P><asp:RadioButtonList ,buff[i]));}// 粘贴到文本框,用户可从中复制TextBox1.Text = sb.ToString();}</script>
http://www.microsoft.com/China/Community/program/originalarticles/TechDoc/Viewstate.mspx
ASP.NET中的ViewState
ViewState是ASP.NET中用来保存WEB控件回传时状态值一种机制。在WEB窗体(FORM)的设置为runat="server",这个窗体(FORM)会被附加一个隐藏的属性_VIEWSTATE。_VIEWSTATE中存放了所有控件在ViewState中的状态值。
ViewState是类Control中的一个域,其他所有控件通过继承Control来获得了ViewState功能。它的类型是system.Web.UI.StateBag,一个名称/值的对象集合。
当请求某个页面时,ASP.NET把所有控件的状态序列化成一个字符串,然后做为窗体的隐藏属性送到客户端。当客户端把页面回传时,ASP.NET分析回传的窗体属性,并赋给控件对应的值。当然这些全部是由ASP.NET负责的,对用户来说是透明的。
使用ViewState的条件
如果要使用 ViewState,则在 ASPX 页面中必须有一个服务器端窗体标记 (<form runat=server>)。窗体字段是必需的,这样包含 ViewState 信息的隐藏字段才能回传给服务器。而且,该窗体还必须是服务器端的窗体,这样在服务器上执行该页面时,ASP.NET 页面框架才能添加隐藏的字段。
Page 的 EnableViewState 属性值为 true。
控件的 EnableViewState 属性值为 true。
页面本身将 20 字节左右的信息保存在 ViewState 中,用于在回传时将 PostBack 数据和 ViewState 值分发给正确的控件。因此,即使该页面或应用程序禁用了 ViewState,仍可以在 ViewState 中看到少量的剩余字节。
设置ViewState
ViewState可以在控件,页,程序,全局配置中设置。缺省情况下 EnableViewState 为 true 。如果要禁止所有页面 ViewState 功能,可以在程序配置中把 EnableViewState 设为 false 。
在控件中:
<asp:DataGrid EnableViewState="false"%>
或
DataGrid1.EnableViewState = false;
在页中:
<%@ Page EnableViewState="false" %>
或
Page.EnableViewState = false;
在程序中:
在web.config中加入 <pages enableViewState="false" />
在全局配置:
在machine.config中修改 <pages enableViewState="false" />
EnableViewState优先级别:
全局配置 < 程序 < 页 < 控件
注意:下列服务器控件不能禁止ViewState
Textbox
Checkbox
Checkbox List
RadioButtonList
上面控件的状态通过IPostBackEventHandler 和 IPostBackDataHandler接口处理,而不是ViewState的机制,所以EnableViewState没有效果。
ViewState对象
在页面回传间通信,ASP中一般利用窗体的属性和 session 来存放数据,在 ASP.NET 中也可以使用 ViewState 对象来做同样的处理。
在ViewState存放数据:
ViewState[key] = value;
或
ViewState.Add(key, value);
取出数据:
TempStr = ViewState[key];
key不存在时返回空。
不能通过ViewState对象来访问控件的值。
动态建立控件的ViewState:
当需要动态地建立一个服务器控件,如下建立了一个 RadioButton 控件并加入到窗体控件集合中:
RadioButton rb = new RadioButton();
Page.Controls[1].Controls.Add(pc);
上面的代码增加一个控件到控件集合末,同样也可以插入到已有控件中的任何位置。
RadioButton rb = new RadioButton();
Page.Controls[1].Controls.AddAt(1,pc);
通常,这些动态生成的控件的状态也需要生成到 ViewState 中去,但这个功能并没有完全实现,特别是生成的控件插入到已有的控件中时。
当动态生成控件和已有控件并存时 ViewState 的结果是不可预料的。在页面回传时,首先非动态生成的控件在ASPX页中被生成,并在 Page_Init
和 Page_Load 事件中读取 ViewState。当页面的控件读取 ViewState 的值时,那些动态生成的控件却还没有被生成,所以当动态生成的控件被
生成时,页面就会省略掉ViewState或者以剩下或许错误的 ViewState 来填充控件。
所以,当需要插一个动态生成的控件到已有控件中去时,最好把这个控件的 ViewState 通过EnableViewState禁止掉。
提醒:
1. 当存在页面回传时,不需要维持控件的值就要把 ViewState 禁止。
2. ViewState的索引是大小写敏感的。
3. ViewState不是跨页面的。
4. 为了能包存在 ViewState 中,对象必须是可流化或者定义了 TypeConverter。
5. 控件 TextBox 的 TextMode 属性设置为 Password时,它的状态将不会被保存在 ViewState 中,这应该是出于安全性的考虑。
6. 在页面 没有回传 或 重定向 或 在回传中转到(transfer)其他页面 时不要使用 ViewState。
7. 在动态建立控件时要小心它的 ViewState。
8. 当禁止一个程序的 ViewState 时,这个程序的所有页面的 ViewState 也被禁止了。
9. 只有当页面回传自身时 ViewState 才是持续的。