ViewState - ASP.NET的一个特有存储容器
来源:互联网 发布:js求质数的算法 编辑:程序博客网 时间:2024/04/28 08:04
首先,我不确定是不是只有ASP.NET由ViewState,也不确认它有多特有,只是觉得这个东西对于Web开发MVC分离的进步很有帮助。
所谓的ViewState,就是用来存放关于View的State的地方。以前的存储容器包括Cookies, Session, Application, Cache, Hidden,有时候连传递变量用的QueryString也用作存储容器,但都不是专门用来存储View相关信息的地方,然而由于没有专门存放View相关信息的地方,所以人们只好乱放。不怕过期失效的变量,多数人会选择放在Session里,而且跨页面不会丢失,用户访问几个别的页面回来还能通过Session恢复本页的View。如果需要延长一些时间,而数据又不是很多的话,可以放Cookies,和Session类似。而数据真的很短,而且页面总是提交给自己的情况下,用QueryString作为一些跨页面生命周期的变量的保存方式也可以。而如果页面可以只用Post不用Get传递的话,那么Hidden也是一个很好的选择,因为Hidden容量大,不在地址留下信息。在ASP.NET当中,就是设计到大多数情况都是Post(除了直接链接),所以用Hidden存放和View相关的信息是非常适合的。
既然用Hidden存放就可以了,为什么需要ViewState这样的统一管理呢?最显然的理由就是加密。ViewState不是给用户看或者修改的信息,仅仅是因为View的状态会在页面生命周期之间丢失,所以我们要将这些信息输出到HTML再等Post的时候取回来,对ViewState加密(至少校验)能够确保View正确无误的恢复。ASP.NET内置的ViewState可以方便的设置校验和加密,只要你把可以序列化的对象存进去,它就能够自动序列化并输出到HTML,同时该对象的保存与恢复是跟控件名以及在控件树中的位置相关的,就如ASP.NET控件的其他特性一样,确保了树中不同位置的同ID控件的数据不会被混淆。简而言之,ViewState是保存跨页面生命周期有关变量的最好容器,但它又不能够跨出页面范围称为会话变量的容器(那应该是Session负责的哦),所以是真正符合其名称用来保存View的State的。
有很多ASP.NET的新手不知道ViewState的用途,认为它是ASP.NET的内部对象,平时还是仅用ASP那套公开的对象好了,那就会带来很多麻烦。例如有GridA和GridB两个页面,点击一个条目查看明细都回转到Details页面,同时Details页面要提供返回原来页面的途径(包括原本GridView所浏览到的分页)。如何存储原本页面的状态呢,包括它来自GridA还是GridB以及原来的GridView所在的分页?有人选择用QueryString传递给Details页面,让Details页面构造返回链接时再通过QueryString把状态传回去。显然,原来页面的状态不是对Details的Query(查询),那么用QueryString传递给Details页面是不合适的。也有人选择用Session传递,但是这个状态仅仅做一次传递,难道我对你说一句话也算是Session(会话)?当然不算。用Hidden是一个方法,但是基于我上面所说的ViewState对Hidden的改良,在这种情况下就应该用ViewState作为原本GridA或GirdB的View状态的保存方式,并且在经过Details页面返回之后再还原。需要说明的是,只有ASP.NET 2.0才在内部支持跨页面PostBack,ASP.NET 1.x不支持跨页面PostBack,也无法跨页面接受和保持ViewState。
最后就是使用ViewState需要注意的地方。过量使用ViewState当然有损效率,但这对于网站的数据正确性来说还不至于造成漏洞,真正会造成漏洞的就是ViewState重名。上面不是说了ViewState是根据控件树位置和控件ID保存所以不会重名的吗?在树是静态的情况下确实是这样,但是如果树是动态创建的,而ID则是可能在不同的语义下重复使用的,那就可能破坏数据的正确性了。例如一个DataControl的子控件自动命名为Control_1, Control_2, Control_3等,如果在PostBack后该DataControl被再次DataBind,那么DataSource可能已经改变了,所以需要清除所有的子控件并重新根据DataSource创建它们,此时别忘记了调用ClearChildState方法把子控件的ViewState和ControlState都清除掉,否则当你重新创建子控件而它们的名称还是Control_1, Control_2, Control_3等的时候,就可能会把原来的ViewState加载回去。
所谓的ViewState,就是用来存放关于View的State的地方。以前的存储容器包括Cookies, Session, Application, Cache, Hidden,有时候连传递变量用的QueryString也用作存储容器,但都不是专门用来存储View相关信息的地方,然而由于没有专门存放View相关信息的地方,所以人们只好乱放。不怕过期失效的变量,多数人会选择放在Session里,而且跨页面不会丢失,用户访问几个别的页面回来还能通过Session恢复本页的View。如果需要延长一些时间,而数据又不是很多的话,可以放Cookies,和Session类似。而数据真的很短,而且页面总是提交给自己的情况下,用QueryString作为一些跨页面生命周期的变量的保存方式也可以。而如果页面可以只用Post不用Get传递的话,那么Hidden也是一个很好的选择,因为Hidden容量大,不在地址留下信息。在ASP.NET当中,就是设计到大多数情况都是Post(除了直接链接),所以用Hidden存放和View相关的信息是非常适合的。
既然用Hidden存放就可以了,为什么需要ViewState这样的统一管理呢?最显然的理由就是加密。ViewState不是给用户看或者修改的信息,仅仅是因为View的状态会在页面生命周期之间丢失,所以我们要将这些信息输出到HTML再等Post的时候取回来,对ViewState加密(至少校验)能够确保View正确无误的恢复。ASP.NET内置的ViewState可以方便的设置校验和加密,只要你把可以序列化的对象存进去,它就能够自动序列化并输出到HTML,同时该对象的保存与恢复是跟控件名以及在控件树中的位置相关的,就如ASP.NET控件的其他特性一样,确保了树中不同位置的同ID控件的数据不会被混淆。简而言之,ViewState是保存跨页面生命周期有关变量的最好容器,但它又不能够跨出页面范围称为会话变量的容器(那应该是Session负责的哦),所以是真正符合其名称用来保存View的State的。
有很多ASP.NET的新手不知道ViewState的用途,认为它是ASP.NET的内部对象,平时还是仅用ASP那套公开的对象好了,那就会带来很多麻烦。例如有GridA和GridB两个页面,点击一个条目查看明细都回转到Details页面,同时Details页面要提供返回原来页面的途径(包括原本GridView所浏览到的分页)。如何存储原本页面的状态呢,包括它来自GridA还是GridB以及原来的GridView所在的分页?有人选择用QueryString传递给Details页面,让Details页面构造返回链接时再通过QueryString把状态传回去。显然,原来页面的状态不是对Details的Query(查询),那么用QueryString传递给Details页面是不合适的。也有人选择用Session传递,但是这个状态仅仅做一次传递,难道我对你说一句话也算是Session(会话)?当然不算。用Hidden是一个方法,但是基于我上面所说的ViewState对Hidden的改良,在这种情况下就应该用ViewState作为原本GridA或GirdB的View状态的保存方式,并且在经过Details页面返回之后再还原。需要说明的是,只有ASP.NET 2.0才在内部支持跨页面PostBack,ASP.NET 1.x不支持跨页面PostBack,也无法跨页面接受和保持ViewState。
最后就是使用ViewState需要注意的地方。过量使用ViewState当然有损效率,但这对于网站的数据正确性来说还不至于造成漏洞,真正会造成漏洞的就是ViewState重名。上面不是说了ViewState是根据控件树位置和控件ID保存所以不会重名的吗?在树是静态的情况下确实是这样,但是如果树是动态创建的,而ID则是可能在不同的语义下重复使用的,那就可能破坏数据的正确性了。例如一个DataControl的子控件自动命名为Control_1, Control_2, Control_3等,如果在PostBack后该DataControl被再次DataBind,那么DataSource可能已经改变了,所以需要清除所有的子控件并重新根据DataSource创建它们,此时别忘记了调用ClearChildState方法把子控件的ViewState和ControlState都清除掉,否则当你重新创建子控件而它们的名称还是Control_1, Control_2, Control_3等的时候,就可能会把原来的ViewState加载回去。
- ViewState - ASP.NET的一个特有存储容器
- ViewState - ASP.NET 的一个特有存储容器
- ASP.Net中用ViewState存储自定义复杂对象后类型转换的一个问题
- asp.net 的viewstate
- ASP.Net ViewState的实现
- ASP.Net ViewState的实现
- ASP.Net ViewState的实现
- ASP.Net ViewState的实现
- ASP.Net ViewState的实现
- ASP.NET ViewState的介绍
- 真正理解ASP.NET的ViewState (Truly Understanding ViewState)
- 真正理解ASP.NET的ViewState (Truly Understanding ViewState)
- 真正理解ASP.NET的ViewState (Truly Understanding ViewState)
- 真正理解ASP.NET的ViewState (Truly Understanding ViewState)
- 真正理解ASP.NET的ViewState (Truly Understanding ViewState)
- 真正理解ASP.NET的ViewState (Truly Understanding ViewState)
- 真正理解ASP.NET的ViewState (Truly Understanding ViewState)
- ASP.NET 小技巧:重写 ViewState 的存储目的地,以提高页面性能
- 覆盖VS重载(override VS overload)
- 如何加入一个已经存在的sf.net项目
- ANT安装、配置
- eXtremeComponent在中文环境下的使用
- 在oracle 10.2 for solaris上手工建立第2个数据库并访问的办法
- ViewState - ASP.NET的一个特有存储容器
- 如何做业务员
- Java学习的RoadMap
- JAVA问题集合
- 用C编写Windows服务程序的五个步骤
- 怎么样才能成为一个优秀的业务员
- C语言面试题大汇总
- 正式安装和试用一下
- jni入门学习笔记(一)