** 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 页面中必须有一个服务器端窗体标记 (
1<form runat="server">) 。窗体字段是必需的,这样包含 ViewState 信息的隐藏字段才能回传给服务器。而且,该窗体还必须是服务器端的窗体,这样在服务器上执行该页面时, ASP.NET 页面框架才能添加隐藏的字段。
2Page 的 EnableViewState 属性值为 true 。
3控件的 EnableViewState 属性值为 true 。
4
5页面本身将 20 字节左右的信息保存在 ViewState 中,用于在回传时将 PostBack 数据和 ViewState 值分发给正确的控件。因此,即使该页面或应用程序禁用了 ViewState ,仍可以在 ViewState 中看到少量的剩余字节。
6
7** 设置 ** ** ViewState **
8ViewState 可以在控件,页,程序,全局配置中设置。缺省情况下 EnableViewState 为 true 。如果要禁止所有页面 ViewState 功能,可以在程序配置中把 EnableViewState 设为 false 。
9在控件中:
10
11<asp:datagrid %="" enableviewstate="false">
12
13或
14
15DataGrid1.EnableViewState = false;
16
17在页中:
@ Page EnableViewState="false"
1
2或
3
4Page.EnableViewState = false;
5
6在程序中:
7
8在 web.config 中加入 <pages enableviewstate="false"></pages>
9
10在全局配置:
11
12在 machine.config 中修改 <pages enableviewstate="false"></pages>
13
14EnableViewState 优先级别:
15全局配置 < 程序 < 页 < 控件
16
17注意:下列服务器控件不能禁止 ViewState
18
19Textbox
20Checkbox
21Checkbox List
22RadioButtonList
23
24上面控件的状态通过 IPostBackEventHandler 和 IPostBackDataHandler 接口处理,而不是 ViewState 的机制,所以 EnableViewState 没有效果。
25
26ViewState 对象
27在页面回传间通信, ASP 中一般利用窗体的属性和 session 来存放数据,在 ASP.NET 中也可以使用 ViewState 对象来做同样的处理。
28在 ViewState 存放数据:
29
30ViewState[key] = value;
31
32或
33
34ViewState.Add(key, value);
35
36取出数据:
37
38TempStr = ViewState[key];
39key 不存在时返回空。
40
41不能通过 ViewState 对象来访问控件的值。
42
43动态建立控件的 ViewState:
44当需要动态地建立一个服务器控件,如下建立了一个 RadioButton 控件并加入到窗体控件集合中:
45
46RadioButton rb = new RadioButton();
47Page.Controls[1].Controls.Add(pc);
48
49上面的代码增加一个控件到控件集合末,同样也可以插入到已有控件中的任何位置。
50
51RadioButton rb = new RadioButton();
52Page.Controls[1].Controls.AddAt(1,pc);
53
54通常,这些动态生成的控件的状态也需要生成到 ViewState 中去,但这个功能并没有完全实现,特别是生成的控件插入到已有的控件中时。
55当动态生成控件和已有控件并存时 ViewState 的结果是不可预料的。在页面回传时,首先非动态生成的控件在 ASPX 页中被生成,并在 Page_Init
56和 Page_Load 事件中读取 ViewState 。当页面的控件读取 ViewState 的值时,那些动态生成的控件却还没有被生成,所以当动态生成的控件被
57生成时,页面就会省略掉 ViewState 或者以剩下或许错误的 ViewState 来填充控件。
58
59所以,当需要插一个动态生成的控件到已有控件中去时,最好把这个控件的 ViewState 通过 EnableViewState 禁止掉。
60
61** 提醒: **
621\. 当存在页面回传时,不需要维持控件的值就要把 ViewState 禁止。
632\. ViewState 的索引是大小写敏感的。
643\. ViewState 不是跨页面的。
654\. 为了能包存在 ViewState 中,对象必须是可流化或者定义了 TypeConverter 。
665\. 控件 TextBox 的 TextMode 属性设置为 Password 时,它的状态将不会被保存在 ViewState 中,这应该是出于安全性的考虑。
676\. 在页面 没有回传 或 重定向 或 在回传中转到 (transfer) 其他页面 时不要使用 ViewState 。
687\. 在动态建立控件时要小心它的 ViewState 。
698\. 当禁止一个程序的 ViewState 时,这个程序的所有页面的 ViewState 也被禁止了。
709\. 只有当页面回传自身时 ViewState 才是持续的。
71
72最后略提一句在 Stryon ( http://www.stryon.com.cn )公司的产品 iNET (转换 .NET APP 成 Java 代码, http://208.49.57.227:8080/downloads/Default.aspx )中用 Java ** 实现 ** ** ViewState ** ** ,使用上没什么区别。 ** ** **</asp:datagrid></form>