ViewState探索
什么是 view state?
View State是客户端状态管理重要机制之一。当页面PostBack(向服务器发送或获得数据)时,它能存储页面的值。
ASP.NET把View State属性作为页面面内置的结构。当多个请求相同的页面时自动存储数据。
例子:
如果你向加一个变量到View State,
- ViewState["Var"]=Count;
从View State返回数据
- string Test=ViewState["TestVal"];
在返回数据时,经常我们需要对ViewState中的值进行类型转换
view state有那些好处?
* 易于实现
* 不需要服务器资源
* 可增强安全性 ,它能被压缩或编码。
view state有那些缺点?
* 如果保存比较大的数据,将增加性能开销。因为它和页面相关。
* 如果它把数据以散列格式存放在隐藏域中,容易被捕获
* 在移动设备中不被支持。
什么时候使用view state?
当你选择View State作为维护页面状态的机制时,应该记住下面几点:
* 数据应该比较小,因为数据和页面控件绑定。数据量大,导致性能开销多大。
* 避免在view state存储安全要求高的数据。
什么时候避免使用view state?
在下列情况下,控件不需要view state:
* 控件从不改变
* 控件每次PostBack重新构建
* 控件时input类型,只有用户才能改变
view state存在那里?
View State把页面控件的值散列,编码为一个字符串。它仅包含页面和控件信息。它和服务器没有交互。它一直保存在客户端浏览器的页面里。ViewState使用隐藏域保存这些编码后的信息。
假想你写一段简单的代码,保存控件的值:
- ViewState["Value"] = MyControl.Text;
运行应用程序,在浏览器,右键 > 查看源文件。 你将得到下面代码块。
值看起来向被加密的字符串。这是Base64编码。这不是加密字符串,所以易于解码。
在view state怎么存储对象?
我们能容易的存储一个对象,就像存储字符串,和int类型的变量。但我们需要把它转为字节流,因为ViewState存储数据在页面隐藏域中。所以我们需要序列化。如果要存放在view state中的数据没有被序列化,将出现错误。
- [Serializable]
- public class student
- {
- public int Roll;
- public string Name;
- public void AddStudent(int intRoll,int strName)
- {
- this.Roll=intRoll;
- this.Name=strName;
- }
- }
把类student的对象存储在view state.
- //Store Student Class in View State
- student _objStudent = new student();
- _objStudent.AddStudent(2, "Abhijit");
- ViewState["StudentObject"] = _objStudent;
- //Retrieve Student information view state
- student _objStudent;
- _objStudent = (student)ViewState["StudentObject"];
怎么跟踪view state信息?
如果想跟踪view state信息, 通过Page指令的Trace属性为true。
- <%@ Page Language="C#" Trace="true"
运行web应用程序。你将在树状控件区看到控件ID,和ViewState大小等详细信息。不要担心"Render Size Byte" , 它是控件的大小。
启用或禁止View State
你可以启用或禁止单个控件View state,也可以启用或禁止页面级别的View State.设置控件EnableViewState属性false,可以关掉单个控件的View State.例如:
- TextBox1.EnableViewState =false;
通过Page指令的EnableViewState属性为false.关闭整个页面的View State.
- <%@ Page Language="C#" EnableViewState="false"
即使禁止了整个页面的View State.你将看到在隐藏的view state标签中仍然保存少量信息。这是因为ASP.NET一直最少量的保存控件的层级关系信息。即使View State被关闭了。
为了启动View State,你需要把相应的数据设置为True.下面是一个启动单个控件View State的例子:
- TextBox1.EnableViewState =true;
启动页面级别ViewState的例子:
- <%@ Page Language="C#" EnableViewState="true"
怎么保证View State的安全性?
我已经说了View State信息是以Base64字符串编码保存在隐藏域中。它看起来象:
许多ASP.NET程序员以为这是被加密的格式。我再说一次,这不是加密的字符串,它很容易被破解。为了确保View State的安全,可以进行两个设置:
* 首先,你要确保View State信息使用"hash code"防干扰的。 可以通过Page指令 EnableViewStateMAC属性为true. MAC 代表"Message Authentication Code"
- <%@ Page Language="C#" EnableViewState="true" EnableViewStateMac="true"
hash code(保密性强的校验)由ASP.NET计算出。被附加到View State内容中保存于隐藏域。再下次PostBack时,那个校验码被验证。如果有错误,Post Back将被拒绝,我们也可以再web.config中设置该属性。
* 第二个设置是:通过Page指令ViewStateEncryptionMode属性为Always。这将加密View State数据。如下设置:
- <%@ Page Language="C#" EnableViewState="true" ViewStateEncryptionMode="Always"
ViewStateEncryptionMode 有三个可选项:
* Always
* Auto
* Never
Always意味着View State一直被加密。Never意味者从来不加密。Auto意味着对特别指定的控件加密,该控件必须调用Page.RegisterRequiresViewStateEncryption()方法请求加密。
也可以在web.config中设置 "EnableViewStateMAC" 和 ViewStateEncryptionMode"
- <system.web>
- <pages viewStateEncryptionMode ="Always"
- enableViewStateMac ="true"/>
- </system.web>
注意 : 避免不必要的加密。因为这导致性能问题。
一些重要点
问题 | 回答 |
---|---|
客户端还是服务器端 | 客户端 |
是否使用服务器资源 | 否 |
是否易于实现 | 是 |
是否有性能问题 | 对于大数据,加密,解密会有 |
支持加密解密? | 支持 |
能存储对象? | 可以。但需要在类上加serialize关键字 |
会超时吗? | 不会 |
什么是 view state?
View State是客户端状态管理重要机制之一。当页面PostBack(向服务器发送或获得数据)时,它能存储页面的值。
ASP.NET把View State属性作为页面面内置的结构。当多个请求相同的页面时自动存储数据。
例子:
如果你向加一个变量到View State,
- ViewState["Var"]=Count;
从View State返回数据
- string Test=ViewState["TestVal"];
在返回数据时,经常我们需要对ViewState中的值进行类型转换
view state有那些好处?
* 易于实现
* 不需要服务器资源
* 可增强安全性 ,它能被压缩或编码。
view state有那些缺点?
* 如果保存比较大的数据,将增加性能开销。因为它和页面相关。
* 如果它把数据以散列格式存放在隐藏域中,容易被捕获
* 在移动设备中不被支持。
什么时候使用view state?
当你选择View State作为维护页面状态的机制时,应该记住下面几点:
* 数据应该比较小,因为数据和页面控件绑定。数据量大,导致性能开销多大。
* 避免在view state存储安全要求高的数据。
什么时候避免使用view state?
在下列情况下,控件不需要view state:
* 控件从不改变
* 控件每次PostBack重新构建
* 控件时input类型,只有用户才能改变
view state存在那里?
View State把页面控件的值散列,编码为一个字符串。它仅包含页面和控件信息。它和服务器没有交互。它一直保存在客户端浏览器的页面里。ViewState使用隐藏域保存这些编码后的信息。
假想你写一段简单的代码,保存控件的值:
- ViewState["Value"] = MyControl.Text;
运行应用程序,在浏览器,右键 > 查看源文件。 你将得到下面代码块。
值看起来向被加密的字符串。这是Base64编码。这不是加密字符串,所以易于解码。
在view state怎么存储对象?
我们能容易的存储一个对象,就像存储字符串,和int类型的变量。但我们需要把它转为字节流,因为ViewState存储数据在页面隐藏域中。所以我们需要序列化。如果要存放在view state中的数据没有被序列化,将出现错误。
- [Serializable]
- public class student
- {
- public int Roll;
- public string Name;
- public void AddStudent(int intRoll,int strName)
- {
- this.Roll=intRoll;
- this.Name=strName;
- }
- }
把类student的对象存储在view state.
- //Store Student Class in View State
- student _objStudent = new student();
- _objStudent.AddStudent(2, "Abhijit");
- ViewState["StudentObject"] = _objStudent;
- //Retrieve Student information view state
- student _objStudent;
- _objStudent = (student)ViewState["StudentObject"];
怎么跟踪view state信息?
如果想跟踪view state信息, 通过Page指令的Trace属性为true。
- <%@ Page Language="C#" Trace="true"
运行web应用程序。你将在树状控件区看到控件ID,和ViewState大小等详细信息。不要担心"Render Size Byte" , 它是控件的大小。
启用或禁止View State
你可以启用或禁止单个控件View state,也可以启用或禁止页面级别的View State.设置控件EnableViewState属性false,可以关掉单个控件的View State.例如:
- TextBox1.EnableViewState =false;
通过Page指令的EnableViewState属性为false.关闭整个页面的View State.
- <%@ Page Language="C#" EnableViewState="false"
即使禁止了整个页面的View State.你将看到在隐藏的view state标签中仍然保存少量信息。这是因为ASP.NET一直最少量的保存控件的层级关系信息。即使View State被关闭了。
为了启动View State,你需要把相应的数据设置为True.下面是一个启动单个控件View State的例子:
- TextBox1.EnableViewState =true;
启动页面级别ViewState的例子:
- <%@ Page Language="C#" EnableViewState="true"
怎么保证View State的安全性?
我已经说了View State信息是以Base64字符串编码保存在隐藏域中。它看起来象:
许多ASP.NET程序员以为这是被加密的格式。我再说一次,这不是加密的字符串,它很容易被破解。为了确保View State的安全,可以进行两个设置:
* 首先,你要确保View State信息使用"hash code"防干扰的。 可以通过Page指令 EnableViewStateMAC属性为true. MAC 代表"Message Authentication Code"
- <%@ Page Language="C#" EnableViewState="true" EnableViewStateMac="true"
hash code(保密性强的校验)由ASP.NET计算出。被附加到View State内容中保存于隐藏域。再下次PostBack时,那个校验码被验证。如果有错误,Post Back将被拒绝,我们也可以再web.config中设置该属性。
* 第二个设置是:通过Page指令ViewStateEncryptionMode属性为Always。这将加密View State数据。如下设置:
- <%@ Page Language="C#" EnableViewState="true" ViewStateEncryptionMode="Always"
ViewStateEncryptionMode 有三个可选项:
* Always
* Auto
* Never
Always意味着View State一直被加密。Never意味者从来不加密。Auto意味着对特别指定的控件加密,该控件必须调用Page.RegisterRequiresViewStateEncryption()方法请求加密。
也可以在web.config中设置 "EnableViewStateMAC" 和 ViewStateEncryptionMode"
- <system.web>
- <pages viewStateEncryptionMode ="Always"
- enableViewStateMac ="true"/>
- </system.web>
注意 : 避免不必要的加密。因为这导致性能问题。
一些重要点
问题 | 回答 |
---|---|
客户端还是服务器端 | 客户端 |
是否使用服务器资源 | 否 |
是否易于实现 | 是 |
是否有性能问题 | 对于大数据,加密,解密会有 |
支持加密解密? | 支持 |
能存储对象? | 可以。但需要在类上加serialize关键字 |
会超时吗? | 不会 |