为什么你会在Session存储对象上使用asp.net的ViewState存储对象?

时间:2009-02-22 19:38:33

标签: asp.net viewstate storage session-storage

除了会话存储是多个页面的会话全局之外,为什么还要使用viewstate来保存值?

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

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

但是为什么还有页面变量和对象的viewstate存储?

也许我错过了该页面的viewstate存储的另一个很好的用途,有没有人知道那里的东西?

感谢阅读!

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

8 个答案:

答案 0 :(得分:22)

会话耗尽,Viewstate没有 - 您可以在一小时后返回,您的查看状态仍然可用。当您在网站上返回/转发时,Viewstate也始终可用,会话更改。

答案 1 :(得分:11)

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

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

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

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

一般来说,没有“正确”的答案可供使用。这完全取决于你想要实现的目标。

大多数控件应该使用Viewstate。如果您正在处理敏感信息,请考虑会话。如果您拥有适用于特定页面集的数据,请使用viewstate。如果是用户访问您网站时需要的数据,请参加会议。

答案 2 :(得分:5)

例如,当您的应用程序可能在计算机服务器场中运行而您无法配置会话以使用sql server时。(或者使用sql server太过性能损失)

答案 3 :(得分:5)

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

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

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

答案 4 :(得分:4)

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

在内部网站点上,所有用户都可以对服务器进行高速LAN访问,但可用于保存会话数据的RAM是有限的,这可能更有意义。

答案 5 :(得分:4)

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

您可以存储viewstate服务器端,从而消除客户端的负载。

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

答案 6 :(得分:2)

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

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

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

<sessionState cookieless="true" />

答案 7 :(得分:1)

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