15

除了因为会话存储对于不止一页来说是会话全局的,为什么还要使用视图状态来保存值?

从客户端到服务器来回发送除了一些小的查询字符串(如值)之外的任何类型的信息似乎有点荒谬。我的意思是浪费带宽(!),只是为了存储目的。会话虽然跨多个页面是全局的,但似乎是视图状态的完全优越的替代方案。

特别是对于 asp.net ajax 控件和变体,视图状态可能很快变得臃肿,跟踪所有这些不同控件和 html 元素的各种状态和变量。

但是,为什么还有页面变量和对象的视图状态存储呢?

也许我错过了页面视图状态存储的另一个很好的用途,有人知道吗?

谢谢阅读!

编辑:每个人都有一个很好的答案,对不起,如果我没有选择你的。

4

8 回答 8

22

会话用完,Viewstate 没有 - 您可以在一小时后返回,您的 viewstate 仍然可用。当您在网站上返回/前进时,视图状态也始终可用,会话发生变化。

于 2009-02-22T19:44:13.687 回答
11

Viewstate 或 Session 的全部原因是将 Web 从无状态系统转变为动态的定制体验。当用户请求一个页面时,您可以从用户停止的地方继续进行体验的唯一方法是记住服务器或用户客户端上的状态。

Viewstate 是一种在客户端记住用户状态的机制。会话是一种在服务器上记住用户状态的机制。

Viewstate 是一种瞬态存储机制。使用 viewstate 的控件将其状态作为隐藏输入呈现到 html 页面中。为了防止篡改,它被签名。但是,它没有加密,因此您可能希望避免将任何敏感信息放在那里。Viewstate 对于您想要跨一系列多个请求(页面加载)发布的情况很有用。这方面的一个示例是当表单未验证时,因为用户可能输入了错误的电子邮件地址或其他内容,并且您希望将表单恢复为用户提交之前的状态。这样做的缺点是视图状态是一个饥饿的野兽,可以轻松地将页面大小增加 30-50%。

另一方面,会话存储在服务器上。客户端得到一个令牌,告诉服务器哪个内存块是他们的。这可能比视图状态更安全,因为数据不会一遍又一遍地重新传输给用户。不过也有取舍。您的服务器可能内存不足。或者,如果会话中断,用户可能会丢失数据。

一般来说,没有“正确”的答案可供使用。这完全取决于您要完成的工作。

大多数与控件有关的事情都应该使用 Viewstate。但是,如果您正在处理敏感信息,请考虑使用 Session。如果您有一组特定页面的数据,请使用 viewstate。如果您在用户访问您的网站期间需要数据,请考虑 Session。

于 2009-02-22T23:39:14.170 回答
5

例如,当您的应用程序可能在计算机场中运行并且您无法将会话配置为使用 sql server 时。(或者使用 sql server 对性能的影响太大)

于 2009-02-22T19:42:40.197 回答
5

ViewState 和 Session 有不同的作用域。ViewState 旨在在“回发”期间存储或多或少的瞬态数据,而 session 用于保存关键会话状态数据。我建议将 ViewState 用于与特定“页面会话”相关的状态。

如果您不喜欢 ViewState 的正常行为,那么编写自己的 PageStatePersister 并让该对象执行持久性非常简单,例如使用 session 或 Memcached 之类的东西。然后,您可以完全覆盖默认的持久性机制。

然后,好处是您可以无缝地继续使用 .NET Framework 中的标准 Web 控件,这些控件都将使用 ViewState/ControlState 来处理此类数据,而不会导致 ViewState 膨胀。服务器内存持久性机制可能非常有效。

于 2009-02-22T21:31:01.950 回答
4

ViewState 本质上只是一个隐藏的输入,必须上传到服务器并与每个请求一起解析。该字段通常是自动填充的,通常程序员完全不知道,并且可以变得非常大。对于许多存在问题的站点来说,因为即使是宽带用户也有非常有限的上行带宽。

在所有用户都可以通过高速 LAN 访问服务器但可用于保存会话数据的内存有限的 Intranet 站点上,这可能更有意义。

于 2009-02-22T19:59:00.360 回答
4

不是真正直接回答您的问题,但它可能会解决您的问题。

您可以在服务器端存储视图状态,从而消除客户端的负载。

创建一个继承页面的类,并覆盖 PageStatePersister。 http://msdn.microsoft.com/en-us/library/system.web.ui.sessionpagestatepersister.aspx

 public class RussPage : Page
    {
         protected override PageStatePersister PageStatePersister
        {
            get
            {
                return new SessionPageStatePersister(Page);
            }
        }
    }
于 2009-02-23T15:38:26.407 回答
2

不是您问题的答案,而是您的一个假设是不正确的。

会话 ID 可以在 URL 中传递。会话不需要 cookie。

http://msdn.microsoft.com/en-us/library/aa479314.aspx

<sessionState cookieless="true" />
于 2009-02-22T21:23:35.803 回答
1

您正在做一个应用程序,在大多数情况下,视图状态膨胀不是问题,那么最好将特定于页面的数据存储在视图状态中,因为它可以帮助您的服务器更好地执行。如果您对会话或任何缓存发疯,就此而言,您可能会伤害自己,而不是帮助自己。

于 2009-02-22T19:52:06.883 回答