【问题标题】:Why is viewstate serialized to a hidden field in the form and not kept on the server?为什么视图状态被序列化到表单中的隐藏字段而不保存在服务器上?
【发布时间】:2012-08-15 09:11:51
【问题描述】:

我对 WebForms 很陌生,我正在尝试了解 ViewState。今天 AFAIK,它通过回发到同一页面来保持对 UI 的修改。但是为什么它将状态(= 存储的修改)发送到客户端并且不将其保留在服务器上节省 CPU 周期和带宽?

我的理解完全错误吗?

【问题讨论】:

  • 服务器应该如何跟踪视图状态,因为 HTTP 是无状态的?
  • @Oded:好点,但我认为回发调用已经包含足够的信息。它必须告诉服务器,用户接下来想做什么。当前状态可以保存在服务器上。
  • 是什么让回发调用包含所有信息?它如何表明价值观发生了变化?
  • 您需要记住 HTTP 是无状态的。您还需要牢记网络农场。不能将状态保存在“ 服务器上”,因为“服务器”很容易成为“许多服务器”。
  • 还请记住,默认情况下,ViewState 存储在隐藏的表单字段中。无论表单数据去哪里,ViewState 都可以去,无论它是否回发到同一页面。

标签: asp.net webforms viewstate


【解决方案1】:

顾名思义,视图状态是与视图有内在联系的东西,试图在保持这种关系的同时单独管理它并不是一件容易的事。

您需要存储每个页面的视图状态,因此您仍然必须向客户端发送一个 ID,以便能够在回发时获得正确的视图状态。另一个严重的问题是您向客户端发送了一个页面,但您不知道客户端何时或是否将该页面回发到服务器,因此您需要至少在会话到期之前存储视图状态。

这可能会导致服务器资源的浪费,因为所有这些视图状态都是为可能永远不会回发到服务器的用户存储的。如果你保持你的视图状态苗条,你会同意最好的存储位置是发送它。

最后,如果您对客户端的视图状态仍然不满意,您可以覆盖页面的SavePageStateToPersistenceMediumLoadPageStateFromPersistenceMedium 方法并将其保存到另一个媒体。我已经听到很多人抱怨客户端上的视图状态,大多数时候我只是告诉他们继续在服务器上实现对另一种介质的持久性......但是,我相信没有人做过,可能是因为它很复杂你最终会得到一个不那么干净的解决方案。

【讨论】:

  • 我明白了。但是,正如您所建议的,仅使用一个 ID 并将状态与会话一起存储似乎仍然优于我。最好在服务器上使用一些字节而不是通过网络重复发送它们,不是吗?
  • @Marcel 如果您使用Session,那或多或少就是它的作用。但是,如果您的网站拥有庞大的用户,并从多个服务器提供内容……怎么办?该服务器存储现在如何工作和扩展......?
  • 您将使用可能不再有效的数据污染您的会话,并且您将无法清除它,因为您不知道相关页面是否将被回发。
【解决方案2】:

当页面执行回发以将页面的控制树恢复到页面上次呈现时的状态时使用 ViewState。

这允许例如 GridView 控件在回发时保持其状态(GridView 中显示的内容),而无需将其重新绑定到相同的数据。

默认情况下 ViewState 被序列化并发送到客户端的原因是(我猜)这是在客户端执行回发时获取它的最简单方法。

例如,如果用户打开了多个浏览器窗口并加载了相同的页面,并且您将视图状态存储在 Session 中,该怎么办?在这种情况下,将正确的视图状态分配给不同的窗口当然可以解决,但是让客户端显式发布它似乎是最简单的方法。

也就是说,可以将视图状态存储在 Session 中。参见例如this link

通过实现您自己的System.Web.UI.PageStatePersister 可以获得其他可能性。

【讨论】:

  • 好的,所以 ViewState 的持久化方式似乎是大多数情况下最好的方式。另外,感谢您的链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 2015-11-12
  • 2015-03-21
相关资源
最近更新 更多