引言
Web 页面是无状态的 服务器对每一次请求都认为来自不同用户因此变量的状态在连续对同一页面的多次请求之间或在页面跳转时不会被保留在用AspNET 设计开发一个Web系统时 遇到一个重要的问题是如何保证数据在页面间进行正确安全和高效地传送 提供了状态管理等多种技术来解决保存和传递数据问题以下来探讨NET 下的解决此问题的各种方法和各自的适用场合
数据传递的各种方法和分析
使用Querystring 方法
QueryString 也叫查询字符串 这种方法将要传递的数据附加在网页地址(URL)后面进行传递如页面Aaspx 跳转到页面Baspx可以用RequestRedirect(Baspx?参数名称=参数值)方法也可以用超链接<a Baspx?参数名称=参数值>页面跳转后在目标页面中可用Ruquest[参数名称]来接收参数使用QuerySting 方法的优点是实现简单 不使用服务器资源缺点是传递的值会显示在浏览器的地址栏上有被篡改的风险不能传递对象只有在通过URL 请求页时查询字符串才是可行的
利用隐藏域
隐藏域不会显示在用户的浏览器中 一般是在页面中加入一个隐藏控件 与服务器进行交互时把值赋给隐藏控件并提交给下一页面隐藏域可以是任何存储在网页中的与网页有关的信息的存储库使用隐藏域存入数值时用hidden 控件value=数值取出接收数值时用变量=hidden 控件value使用隐藏域的优点是实现简单 隐藏域是标准的HTML 控件不需要复杂的编程逻辑隐藏域在页上存储和读取不需要任何服务器资源几乎所有浏览器和客户端设备都支持具有隐藏域的窗体缺点是存储结构少仅仅支持简单的数据结构存储量少因为它被存储在页面本身所以无法存储较大的值而且大的数据量会受到防火墙和代理的阻止
ViewState
ViewState 是由ASPNET 页面框架管理的一个隐藏的窗体字段当ASPNET 执行某个页面时该页面上的ViewState 值和所有控件将被收集并格式化成一个编码字符串 然后被分配给隐藏窗体字段的值属性使用ViewState 传递数据时可用ViewState [ 变量名]=数值在取出数据时用变量=ViewState[变量名]使用ViewState 的优点是在对同一页的多个请求间自动保留值不用服务器端资源实现简单视图状态中的值经过哈希计算和压缩并且针对Unicode 实现进行编码其安全性要高于使用隐藏域缺点是因为ViewState 存储在页面本身因此如果
存储较大的值用户显示页和发送页时的速度可能会减慢虽然视图状态以哈希格式存储数据但它仍可以被篡改
使用Cookie
Cookie 可以在页面之间传递少量信息 可以存储在客户端的文本文件中也可存储在客户端的内存中Cookie 方法适用于存储少量页面中经常改动的信息 如为登陆过的网站保存登陆用户名为用户输入提供方便还有在一些用户自定义项目上保存用户的个性化设置使用Cookie传递数据时可用ResponseCookies[键名]=键值取出数据用变量名=RequestCookies[键名]使用Cookie 优点是Cookie 存储在客户端 不使用服务器资源实现简单可配置到期时间缺点是可以存储的数据量比较少由于Cookie 并不被所有的浏览器支持而且还可能被用户禁止或删除所以不能用于保存关键数据另外Cookie 保存的形式是简单的明文文本在它里面不宜保存敏感的未加密的数据
使用Application 变量
使用Application 变量也可以实现页面间的传值Application变量是全局性的所有用户共享一个Application 变量一旦定义它将影响到程序的所有部分如果想在整个应用程序范围使用某个变量值Application 对象将是最佳的选择存入数据时 把值添加到Application 变量里Application[变量名]=数值取出数据用变量=Application[变量名]在不需要使用该Application 时要显式清除它Application[量名]=null
Application 优点易于使用全局范围可供应用程序中的所有页来访问缺点若保存数据的服务器端进程被损坏(如因服务器崩溃升级或关闭而损坏)那么数据就会丢失所以利用Application 一定要有保底的策略占用服务器端的内存这可能会影响服务器的性能以及应用程序的可伸缩性
使用Session 变量
Session 对象可以用来存储需要维护的指定对话的信息不同的客户端生成不同的Session 对象Session 用于存储特定于单独会话的短期信息Session 的使用方法和格式与Application 相同
优点易于实现并且提供较高的安全性和持久性可以应对IIS 重启和辅助进程重启可在多进程中使用缺点是耗用服务器端的内存所以不要存储大量的信息Session 最常见的用途是与Cookie 一起向Web 应用程序提供用户标识功能Session也可用于不支持Cookie 的浏览器但是使用无Cookie 的Session 需要将会话标识符放置在查询字符串中同样会遇到本文在查询字符串一节中陈述的安全问题
使用类的静态属性
这种方法是利用类的静态属性实现两个页面间的值传定义一个包含静态属性的类将要传送的值赋给静态属性目标页面中可以通过静态属性获得源页面中要传的值
优点是可以方便传送多个数据缺点是需要额外编程增加
程序设计的工作量占用服务器内存
使用ServerTransfer
通过ServerTransfer 方法把执行流程从当前的ASPX 文件转到同一服务器上的另一个ASPX 页面的同时可保留表单数据或查询字符串做法是把该方法的第二个参数设置成True在第一个页面用ServerTransfer(目标页面名aspxtrue)目标页面取出数据用RuquestForm[控件名称]或RuquestQueryString[控件名称] 中还可以这样来用代码如下
PreviousPage pg pg=(PreviousPage)ContextHandler ResponseWrite(pgName)
说明 此段代码用在目标页面中取出传递的值Previous Page 是原页面的类名Name 是在原页面定义的属性 需要传递 的数据存入到此属性中
使用这种方法 需要写一些代码以创建一些属性以便可以 在另一个页面访问它 可以在另一个页面以对象属性的方式来 存取数值这个方法在页面间值传递中是特别有用的这种方法 不但简洁同时又是面向对象的
Cache
Cache 具有强大的数据操作功能 以键值对集合的形式存 储数据可以通过指定关键字来插入和检索数据项它的基于依 赖性的终止功能 使它能够精确控制如何并及时更新和消除缓 存中的数据它可以内部进行锁定管理不需要象Application 对象那样使用Lock()和Unlock()方法进行串行化管理缺点是使用 方法较复杂使用不当反而降低性能
不同页面跳转情况下可采用的传值方法
情况一源页面可以跳转到目标页面源页面传递数据给目标页面
使用查询字符串 将少量信息从一页传输到另一页以及不 存在安全性问题时是一个简单常用的方法使用ServerTransfer方法可传递表单数据或查询字符串到另一个页面还可以 保存初始页的HttpContext 当目标页和源页面在同一个服务器 时可以用此方法
情况二页面传递数值给自身页面
即在对同一页的多个请求间保留值 ViewState 属性可提供具有基本安全性的功能也可用隐藏域存储少量回发到自身或另一页的页信息时使用不考虑安全性问题时使用
情况三源页面传递数值给目标页面而源页面不能直接连接到目标页面
有多个方法具体用哪个要看具体情况
Application 存储由多个用户使用且更改不频繁的全局信息此时安全性不成为问题不要存储大量的信息Session存储特定于单独会话的短期信息并且需要较高的安全性不要在会话状态中存储大量的信息需要注意将为应用程序中每一会话的生存期创建并维护会话状态对象在支持许多用户的应用程序中 这可能会占用大量服务器资源并影响可缩放性
Cookie 当您需要在客户端存储少量信息以及不存在安全性问题时使用类的静态属性方便传送多个数据
Cache 对象用于单个用户一组用户或所有的用户可以为多个请求长时间高效率的保存数据上述几个方法 不仅用于情况三 前面两种情况都可以使用只是没有必要时尽量少用否则会造成资源浪费或增加程序的复杂性