【发布时间】:2012-02-27 04:41:35
【问题描述】:
谁能给我一个很好的理由为什么 ViewState 默认不存储在服务器上?
为什么不发送一个小的会话令牌来代替 ViewState,然后可以将其映射到服务器上所需的任何 ViewState 信息,以防止整个 ViewState 被多次回发和转发。
我错过了什么吗?
【问题讨论】:
标签: asp.net webforms viewstate
谁能给我一个很好的理由为什么 ViewState 默认不存储在服务器上?
为什么不发送一个小的会话令牌来代替 ViewState,然后可以将其映射到服务器上所需的任何 ViewState 信息,以防止整个 ViewState 被多次回发和转发。
我错过了什么吗?
【问题讨论】:
标签: asp.net webforms viewstate
可扩展性 - 想象一下,如果 100 万用户查看复杂的 WebForms 页面,将需要多少服务器资源。服务器至少需要在会话超时期间保持 ViewState。视图状态的自动服务器端清理也会有问题 - 用户可能同时查看多个页面,因此需要保留所有页面的 ViewState。
编辑 these posts 中讨论了几种关于如何将视图状态移动到服务器的技术。但是,在您这样做之前,最好从不需要它的控件/页面中删除不必要的视图状态(例如,仅查看/无回发渲染)。
我现在猜,但是当 viewstate 是在 10 年前左右设计的时候,32 位服务器上的 1GB RAM 已经差不多了,而且 MS 可能不得不考虑托管服务提供商希望每个服务器加载 100 个应用程序服务器。所以带宽可能被认为比服务器内存和磁盘存储便宜。
【讨论】:
在内存中存储 ViewState 存在许多问题。
如果应用程序被回收,所有使用该应用程序的人的 VS 都会丢失。
它会增加应用程序的内存消耗。如果服务器上只有几个应用程序,这不是问题;但在某些情况下,可能会在一个盒子上托管多个网站。
可扩展性;应用程序越活跃,需要存储的 VS 越多。而且您不能假设 1-1(1 个用户 - 1 个 VS)。用户可以打开多个选项卡,可以返回,使选项卡处于非活动状态等......这会导致:
您将 VS 存储多长时间?将数据编码保存在页面上可确保在用户将网站打开一段时间后它仍然存在。
如果您托管在网络场上会发生什么。我们不能保证用户在每次请求时都会访问同一台机器。
话虽如此,有几个解决方案:
Memcached-Viewstate - 使用 Memcache 将 VS 存储在分布式内存中。这并不理想 - 如果服务器关闭了 VS,则任何将 VS 存储到该服务器的人都会丢失,但允许应用程序池重置而不会出现问题。
SQL-Viewstate - 将 VS 存储在 SQL 数据库中。这会为每个请求添加至少 1 个 DB 读取和 1 个 DB 写入。同样,不理想,但如果 VS 变得难以管理,从数据库获取和设置 VS 比通过 HTTP 发送和接收它更快。
Filesystem-Viewstate - 将 VS 存储在文件系统中。它比 SQL 连接便宜,但需要文件服务器才能在分布式环境中工作。
【讨论】:
它提高了可伸缩性,因为服务器不需要在内存中维护所有这些。可以将视图状态存储在会话中,但通常不建议这样做。
【讨论】:
根本原因是使用客户端视图状态是服务器不知道页面的当前状态。
如果用户着急,在页面上进行多次(部分)回发,不等待响应,浏览器会发出多个部分回发请求,每个请求都会在服务器端创建一个新的视图状态,最终会被刷新浏览器中的初始视图状态。最后用户进行了最后一次回发,此时初始副本已经消失,因此抛出异常。
服务器端视图状态也会影响服务器性能和用户体验。如果用户一天或长时间不与页面交互,服务器上的视图状态将过期。当用户稍后回发页面时,会引发异常。
例如,我观看 40 分钟的 youtube 视频。昨天看了前半部分,没有关闭标签,而是休眠了我的电脑。今天继续看后半段,发回一些东西,如果视图状态在服务器并且过期,页面会出错。
【讨论】: