C# ViewState

ViewState用于维护页面的UI状态,Web是没有状态的,ASP.NET页面也没有状态,它们在到服务器的每个往返过程中被实例化、执行、呈现和处理。作为Web开发人员,您可以使用众所周知的技术(如以会话状态将状态存储在服务器上,或将页面回传到自身)来添加状态。

一、ViewState的原理

  1. 浏览器请求Default.aspx页面
  2. 在服务器端 发现创建的ViewState 这个时候 会自动创建一个名字叫做__VIEWSTATE(双下滑线 全部是大写)的隐藏域;其隐藏域的值经过base64加密以后返回到浏览器端这一加密过程在页面生命周期的SaveState事件中的SaveAllState方法中完成
  3. 当浏览器提交表单的时候 将__VIEWSTATE的隐藏域也一起提交到服务端 这个时候页面生命周期的ReadState事件的ReadAllState方法会将加密后的值反base64解密。最后将值赋值给名字叫做name的ViewState
  4. 最后来操作ViewState中的值

二、ViewState的用法

  1. 定义ViewState属性
public int PageCount{
get{return (int)ViewState["PageCount"];}
set{ViewState["PageCount"]=value;}
}
  1. 使用ViewState的条件
    如果要使用ViewState,则在ASPX页面中必须要有一个服务器端窗体标记(<form runat = "server">)。窗体字段是必须的,这样包含ViewState信息的隐藏字段才能被传回服务器。而且,该窗体还必须是服务器端的窗体,这样在服务器上执行该页面时,ASP.net页面框架才能添加隐藏字段。
    page的EnableViewState 属性值为true
    控件的EnableViewState 属性值为 true
  2. ViewState需要注意的地方
    a. 当存在页面回传时,不需要维持控件的值就要把 ViewState 禁止。
    b. ViewState的索引是大小写敏感的。
    c. ViewState不是跨页面的。
    d. 为了能保存在 ViewState中,对象必须是可流化或者定义了 TypeConverter。
    e. 控件 TextBox 的 TextMode 属性设置为 Password时,它的状态将不会被保存在 ViewState 中,这应该是出于安全性的考虑。
    f. 在页面没有回传或重定向或在回传中转到(transfer)其他页面时不要使用 ViewState。
    g. 在动态建立控件时要小心它的 ViewState。
    h. 当禁止一个程序的 ViewState 时,这个程序的所有页面的 ViewState 也被禁止了。
    i. 只有当页面回传自身时ViewState 才是持续的。
  3. 设置ViewState
    ViewState可以在控件,页,程序,全局配置中设置。缺省情况下 EnableViewState 为 true 。如果要禁止所有页面 ViewState 功能,可以在程序配置中把 EnableViewState 设为 false

三、安全性
    其实,对于viewstate的安全性问题,asp.net还给我们提供了更多的选择。一般如果要保护viewstate有两种方式:一种是防篡改,一种是加密; 一说到防篡改,我们就想起了使用散列代码.。没错, 我们可以在页面顶部加入如下代码:Page EnableViewStateMAC=true。这样asp.net就会自动的在viewstate中追加一个散列码,在页面回传时,服务器根据回传的viewstate生成一个散列码,再与回传的散列码相比较,如果不对,则丢弃该viewstate,同时控件将恢复初试状态。 (默认情况下asp.net是通过SHA1算法而不是md5算法来生成散列,不过这个可以在machine.config里面配置machineKey validation="MD5"即可),而viewstate加密就更简单了,只要在machine.config里设置一下machineKey validation="3DES"即可实现用des加密viewstate了。

四、Session,ViewState用法对比

  1. 基本理论:
    session值是保存在服务器内存上,那么,可以肯定,大量的使用session将导致服务器负担加重. 而viewstate由于只是将数据存入到页面隐藏控件里,不再占用服务器资源,因此, 我们可以将一些需要服务器"记住"的变量和对象保存到viewstate里面. 而sesson则只应该应用在需要跨页面且与每个访问用户相关的变量和对象存储上. 另外,session在默认情况下20分钟就过期,而viewstate则永远不会过期.
  2. 数据类型:
    但viewstate并不是能存储所有的.net类型数据,它仅仅支持String、Integer、Boolean、Array、ArrayList、Hashtable 以及自定义的一些类型.
  3. 其他考虑:
    当然,任何事物都有两面性, 使用viewstate会增加页面html的输出量,占用更都的带宽,这一点是需要我们慎重考虑的. 另外, 由于所有的viewstate都是存储在一个隐藏域里面,用户可以很容易的通过查看源码来看到这个经过base64编码的值.然后再经过转换就可以获取你存储其中的对象和变量值.
    其实,对于viewstate的安全性问题,asp.net还给我们提供了更多的选择.一般如果要保护viewstate有两种方式: 一种是防篡改,一种是加密. 一说到防篡改,我们就想起了使用散列代码. 没错, 我们可以在页面顶部加入如下代码:Page EnableViewStateMAC=true。这样asp.net就会自动的在viewstate中追加一个散列码,在页面回传时,服务器根据回传的viewstate生成一个散列码,再与回传的散列码相比较,如果不对,则丢弃该viewstate,同时控件将恢复初试状态. (默认情况下asp.net是通过SHA1算法而不是md5算法来生成散列,不过这个可以在machine.config里面配置machineKey validation="MD5"即可),而viewstate加密就更简单了, 只要在machine.config里设置一下machineKey validation="3DES"即可实现用des加密viewstate了.

五、常用域对比

  • ViewState:ASP.NET 的 .aspx页面特有,页面级的;
    就是在页面上的一个隐藏域中保存客户端单独使用的数据的一种方式;服务器端控件的值都自动保存在ViewState中;

  • Cookie:HTTP协议下的一种方式,通过该方式,服务器或脚本能够在客户机上维护状态信息;
    就是在客户端保存客户端单独使用的数据的一种方式;就像你的病历本一样,医院直接给你带回家;

  • Session:和.Net提供的辅助进程相关。
    在服务器端保存客户端单独使用的数据的一种方式;就像银行账户,钱都存在银行里,你就拿一张银行卡【所谓的SessionId】回家(写入客户端的Cookie中);

  • Application:在服务器端保存共享数据的一种方式;
    就像银行的单人公共卫生间,谁进去都行,但一次去一个,进去了就锁上门,出来再把锁打开;
    在这里插入图片描述
    本文转载自多篇文章,在此感谢。

没有更多推荐了,返回首页