【问题标题】:Why would you ever use asp.net's ViewState storage object over the Session storage object?为什么你会使用 asp.net 的 ViewState 存储对象而不是 Session 存储对象?
【发布时间】:2009-02-22 19:38:32
【问题描述】:

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

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

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

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

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

感谢阅读!

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

【问题讨论】:

    标签: asp.net viewstate storage session-storage


    【解决方案1】:

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

    【讨论】:

    • 此外,会话基本上是键值对:如果您的用户打开多个选项卡,并且您在会话中存储了一个 ID,那么您就会遇到问题。
    【解决方案2】:

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

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

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

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

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

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

    【讨论】:

    • 我在问题中解决了这个问题。但我有点认为,10 次中有 9 次,使用存储在页面上的唯一键将变量放入会话中比使用视图状态更有意义。我认为会话是“正确”的答案,因为您不会负担带宽。
    • 说得好:“Viewstate 是一种在客户端记住用户状态的机制。Session 是一种在服务器上记住用户状态的机制。” +1
    • 嗯,这是基本的官方文档,但我的问题有点集中在页面视图的默认实现似乎设计不佳。与 .net CLR 的许多小部分一样,它也存在设计缺陷,尽管其中大部分非常可靠。
    【解决方案3】:

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

    【讨论】:

    • 无论如何,您都不希望您的农场使用数据库来存储会话,这比仅使用粘性 IP 慢。会话对于想要扩展到少数用户的网站来说是不利的。
    • 您也可以使用会话服务器。这要快得多,并且将维护场中所有服务器的会话,而不会产生 SQL 会话开销。
    • @Guy,是的,你可以。但这也不总是可能的。在视图状态中保存一小段信息然后购买额外的服务器并将其配置为会话服务器要容易得多。
    • 是的,在使用 SQL 存储会话的情况下,您不希望将 ViewState 存储在会话中。常规会话已经够慢了,但是添加 ViewState 就太糟糕了。
    【解决方案4】:

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

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

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

    【讨论】:

    • 嗯,是的,我不知道关于 PageStatePresister 的事情。感谢您的信息。
    【解决方案5】:

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

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

    创建一个继承页面的类,并覆盖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);
                }
            }
        }
    

    【讨论】:

    • 大约 2 年前我也没有。当谈到 ViewState 与 Session 问题时,我发现这是我的“快乐之地”。
    • 不是说你只是在session中保存viewstate信息吗?那你为什么不直接做呢?
    • 这样做会破坏网站的选项卡式、窗口式或其他“多任务”浏览!会话在打开到同一站点的多个选项卡之间共享,而 ViewState 则不是。
    • @Jeffrey Hantin - 很公平。如果你在那种环境中工作,你需要考虑到这一点。您可以为此类情况创建不同的“页面”子类。任何编程案例都需要考虑并根据情况做出设计决策。
    【解决方案6】:

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

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

    【讨论】:

      【解决方案7】:

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

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

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

      <sessionState cookieless="true" />
      

      【讨论】:

      • 虽然这是一个老话题,但 ASP.NET 安全性经常被掩盖,所以这里是这样的:一般来说,cookieless="true" 由于安全问题不被接受(请参阅将敏感信息排除在外) URL:owasp.org/index.php/…) 因为会话在 URL 上以完整视图传递。 Dino 在文章中提到了这一点:msdn.microsoft.com/en-us/library/…
      【解决方案8】:

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

      【讨论】:

        猜你喜欢
        • 2017-02-26
        • 1970-01-01
        • 1970-01-01
        • 2019-11-17
        • 2013-06-11
        • 1970-01-01
        • 2016-05-08
        • 1970-01-01
        • 2021-12-04
        相关资源
        最近更新 更多