65.9K
CodeProject 正在变化。 阅读更多。
Home

视图状态(ViewState)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2013 年 10 月 11 日

CPOL

5分钟阅读

viewsIcon

39250

ViewState 是允许状态值跨页面回发得以保留的机制。由于网页的无状态性,常规的

视图状态(ViewState)

ViewState 是允许状态值跨页面回发得以保留的机制。

由于网页的无状态性,常规的页面成员变量将无法在回发时保持其值。 当我们希望页面变量在页面回发时保持其值时,我们可以使用 ViewState 来存储该值。 存储在 ViewState 中的值将被序列化并通过隐藏表单输入值发送到客户端浏览器。 当您在浏览器中查看使用 ViewState 的页面的页面源代码时,您可能会看到这个隐藏的 viewstate 输入,它看起来会像这样

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTM1ODM3Nj......." />

这个单一的隐藏字段包含页面上所有控件的所有 viewstate 值。 这是您需要考虑的 viewstate 的一个重要方面。

由于 viewstate(默认情况下)会发送到客户端浏览器,然后以页面上隐藏输入控件的形式返回到服务器,因此在 viewstate 中存储大量数据可能会增加页面大小并影响页面性能。

要禁用控件的 ViewState,您可以将 EnableViewState 属性设置为 false(在 asp.net 2.0 中,ViewState 默认启用)。 当任何控件的 ViewState 被禁用时,它也会自动为其所有子控件禁用。

示例

<asp:Label ID="lblRequestCount" runat="server" EnableViewState="false"></asp:Label>

这并不意味着您应该避免使用 viewstate。但是,您应该始终意识到您在其中存储了什么以及它如何影响您的整体页面大小。

有些人憎恨 ViewState,有些人则热爱它。无论哪种方式,您都可以控制您的 ViewState,所以请控制它!

示例

在 viewstate 中存储小值的简单方法是使用属性而不是成员变量。 这个属性可以使用 viewstate 来存储其值,而不是会丢失回发值的成员变量。 例如,将一个 Integer 存储在 viewstate 中可以这样实现:

Public Property SomeInteger() As Integer

    Get

        Dim o As Object = ViewState("SomeInteger")

        If Not o Is Nothing Then Return DirectCast(o, Integer)           

        Return 0 'a default

    End Get

    Set(ByVal value As Integer)

        ViewState("SomeInteger") = value

    End Set

End Property
public int SomeInteger {

    get {

        object o = ViewState["SomeInteger"];

        if (o != null) return (int)o;

        return 0;

        //a default

    }

    set { ViewState["SomeInteger"] = value; }

}

 

文章

链接

工具

 

将 View State 持久化到页面之外

在某些情况下,特别是当页面中有大量服务器控件或在 view state 中存储大量自定义数据时,页面 view state 数据的大小可能会增加。如您所知,页面的 view state 数据被编码并存储在 HTML 隐藏元素中,并作为页面的一部分发送到客户端。拥有大量的 view state 可能会影响 Web 应用程序的性能,因为它会增加客户端需要下载的总页面大小(包括编码的 view state)。提高页面大小的一种方法显然是控制 view state 中包含的内容。但是,在某些情况下,您可能没有太多选择,只能按原样处理。在这种情况下,您可以压缩 view state 数据或将其存储在页面之外的其他位置,例如会话状态。是的,ASP.NET 确实提供了自定义 view state 存储位置的方法。

为了自定义页面 view state 的持久化部分,您需要重写 Page 类的 SavePageStateToPersistenceMedium 和 LoadPageStateFromPersistenceMedium 方法。 SavePageStateToPersistenceMedium 在 view state 准备好在页面生命周期中持久化时被调用;ASP.NET 会调用此方法并将 view state 对象传递给它,而我们做什么都可以,只要我们能在它通过后者方法 LoadPageStateFromPersistenceMedium 请求时将其返回给 ASP.NET 即可。顾名思义,此方法在状态持久化定制方面执行与前者相反的操作。下面的代码示例展示了如何通过会话 ID 将 view state 存储在会话状态变量中。

protected override object LoadPageStateFromPersistenceMedium ()

{
    return (new LosFormatter().Deserialize ((string)Session[Session.SessionID]));
}

protected override void SavePageStateToPersistenceMedium (object state)
{
    LosFormatter los = new LosFormatter();
    StringWriter sw = new StringWriter();
    los.Serialize (sw, state);
    string vs = sw.ToString ();
    Session[Session.SessionID] = vs;
}

一旦上述代码就位,页面中用于 view state 数据的 HTML 隐藏元素应该为空。

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="" />

另一种选择是压缩 view state 的大小,并将其作为 HTML 隐藏元素的一部分发送到页面,这是默认方式。

另一个主要的改进是将 ViewState 存储到持久化介质中,而不是仅仅使用 Session 变量来保存 ViewState。这个技术在 MSDN 上 Scott Mitchell 的文章 UnderStanding ASP.NET ViewState 中进行了探讨,他详细解释了 ASP.NET ViewState 的一切以及将 ViewState 存储到持久化介质中的算法。 这个算法由 Bilal Haidar 在 http://www.aspalliance.com/ 实现,并且可以通过以下链接查看该技术的详细信息:以正确的方式将 View State 存储到持久化介质中

尽情享用!

© . All rights reserved.