viewstate java_ASP.NET之ViewState

什么是ViewState?

在asp时代, 大家都知道一个html控件的值,比如input 控件值,当我们把表单提交到服务器后, 页面再刷新回来的时候, input里面的数据已经被清空. 这是因为web的无状态性导致的, 服务端每次把html输出到客户端后就不再与客户端有联系.

asp.net巧妙的改变了这一点. 当我们在写一个asp.net表单时, 一旦标明了 form runat=server,那么,asp.net就会自动在输出时给页面添加一个隐藏域

那么,有了这个隐藏域,页面里其它所有的控件的状态,包括页面本身的一些状态都会保存到这个控件值里面.每次页面提交时一起提交到后台,asp.net对其中的值进行解码,然后输出时再根据这个值来恢复各个控件的状态. 我们再看这个控件的value值,它可能类似如下的形式:Oz4+O2w8aTwxPjs+O2w8....

很多人会认为这是加密的信息,其实不是, Microsoft仅仅是给各个控件和页面的状态存入适当的对象里面,然后把该对象序列化, 最后再做一次base64编码,直接赋值给viewstate控件.

说到这,想必你一定想看看这个viewstate里面到底存了哪些东西, 嗯,你是可以写一个base64 to string的转换代码来实现.不过,viewstate是有层次之分的,普通的转换后,你看到的也是很乱的文字. 这里提供了一个专门转换viewstate值的地方 http://www.wilsondotnet.com/Demos/ViewState.aspx .你可以去将自己的viewstate输入进去,让它给你转化一下,这可是带结构的哦

:)

viewstate是如何工作的?

viewstate保存最后一次在服务器上处理的页面状态。它不能保存那些被动态改变的控件的值。

所有的服务器端控件都有一个ViewState属性。如果它是enable的,这个控件的viewstate就起作用了。那viewstate是在哪里,是如何存储的呢?当一个页面第一次加载,所有的控件被序列化到viewstate,保存在一个叫_ViewState的隐藏form字段里。这个隐藏字段对应服务器端的ViewState对象。页面的ViewState使用System.Web.UI.StateBag对象存储键值对。当一个回传发生,页面反序列化ViewState然后恢复所有的控件。页面中保存控件的ViewState以base

64 编码格式存储成name - value。当一个页面重新加载,会调用两个和ViewState相关的方法,LoadViewState 和SaveViewState。下面是我的一个页面中的_ViewState隐藏字段。

启用和禁止ViewState

在默认情况下,所有服务器控件的viewstate开启状态,通过以及几种途径来禁止。

1.页面级别

or

2.控件级别

or

3.应用程序级别

or

4.机器级别

or

在viewstate中保存和取出值

viewstate能处理以下的类型

基本类型,基本类型数组,ArrayList 和Hashtable,任何可以序列化的对象。

以下代码是将ArrayList存到viewstate中并取出

ArrayList obj = new ArrayList();

//Some code

ViewState["ViewStateObject"] = obj;

obj = ViewState["ViewStateObject"];

性能问题

为了更好的页面呈现性能,viewstate应该尽可能的小。要记住Viewstate中的数据会占用很多的网络带宽。因此我们要谨慎的利用viewstate。如果页面和控件不需要回传,那么就要禁止viewstate属性。通常在aspx页面之外保存Viewstate会取得更好的性能表现。为了达到这个目的,我们可以使用SavePageStateToPersistenceMedium 和LoadPageStateFromPersistenceMedium 这两个方法。在web.config或machine.config设置来禁止某个程序的所有页面或全部程序页面的viewstate。

注意只有控件包含在

里才能存储viewstate。然而即使页面所有的viewstate被禁止,页面仍然在viewstate中保存20字节的数据,用来在回传时为相应的控件分配viewstate中的数据。所以当页面完全没有回传,移去runat="server"能减少20字节的数据。如果有很多这样的页面,20字节的节省也能在一定程度上减少带宽。viewstate应该在必要的时候使用。在DataGrid和DataRepeater这样的控件中要避免使用viewstate,因为这些控件的viewstate占用数据相当大。

下面我提供一个简单的用于计算页面viewstate大小的方法。创建一个MasterPageBase类,然后其它所有的页面都要继承它。

public class MasterPageBase: System.Web.UI.Page

{

protected override void OnPreRender(EventArgs e)

{

object viewStateObject = HttpContext.Current.Request["__VIEWSTATE"];

if (viewStateObject == null)

HttpContext.Current.Trace.Warn("The ViewState Size is:", "0");

else

HttpContext.Current.Trace.Warn("The ViewState Size is:",

HttpContext.Current.Request["__VIEWSTATE"].Length.ToString());

base.OnPreRender(e);

}

}

安全问题

可以采取两个措施来避免viewstate被仿冒

使用EnableViewStateMac属性

给 ViewState中的内容加密

EnableViewStateMac会进行一个机器授权验证(MAC),这应在页面级别或程序级别使用。当设置时,这个属性会在viewstate呈现之前附加一个viewstate的hash值。当回传发生时,hash值会被重新计算和核对。如果他们不匹配,页面会拒绝显示,这样就确保了viewstate没有被纂改。

在machine.config中设置对viewstate内容的加密

or

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值