打印本文 打印本文 关闭窗口 关闭窗口
Taking a Bite Out of ASP.NET ViewState
作者:武汉SEO闵涛  文章来源:敏韬网  点击数3085  更新时间:2009/4/23 10:46:57  文章录入:mintao  责任编辑:mintao

Taking a Bite Out of ASP.NET ViewState

Susan Warren
Microsoft Corporation

November 27, 2001

When I meet and talk to new ASP.NET page developers, one of the first things they usually ask me is, "What is that ViewState thing, anyway?" And often you can hear in their voices that same queasy fascination I feel when a waiter in some exotic restaurant parks a plateful of some previously unknown food in front of me. Somebody must think it''''s good; otherwise, they wouldn''''t be serving it. So, I''''ll try it, and maybe even love it, but it sure looks odd!

It''''s that way with ViewState too. Once you get past how it looks, you''''ll find many circumstances where you''''ll be delighted to have ViewState in your ASP.NET application, because it lets you do much more with much less code. But there will also be times when you''''ll want to definitely leave ViewState on the plate. We''''ll look at both scenarios, but first, let''''s answer that question about what is ViewState.

Answer: ViewState Maintains the UI State of a Page

The Web is stateless, and so are ASP.NET Pages. They are instantiated, executed, rendered, and disposed on every round trip to the server. As a Web developer, you can add statefulness using well-known techniques like storing state on the server in Session state or by posting a page back to itself. Take the sign up form in Figure 1 as an example.

Figure 1. Restoring posted form values

You can see I''''ve picked an invalid value for my potluck item. Like most forms on the Web, this one is friendly enough to put a helpful error message and a star next to the field in error. In addition, all of the valid values I entered in the other text boxes and drop-down lists still appear in the form. This is possible, in part, because HTML form elements post their current values from the browser to the server in the HTTP header. You can use ASP.NET tracing to see the form values that are posted back, as in Figure 2.

Figure 2. Values posted in HTTP Form, as shown by ASP.NET trace

Before ASP.NET, restoring the values back into the form fields across multiple postbacks was entirely the responsibility of the page developer, who had to pick them out, one-by-one, from the HTTP form, and push them back into the fields. Happily, ASP.NET does this trick automatically, thus eliminating both a lot of grunt work and a lot of code for forms. But that''''s not ViewState.

ViewState is the mechanism ASP.NET uses to keep track of server control state values that don''''t otherwise post back as part of the HTTP form. For example, the text shown by a Label control is saved in ViewState by default. As a developer, you can bind data or programmatically set the Label just once when the page first loads, and on subsequent postbacks, the label text will be repopulated automatically from ViewState. So in addition to less grunt work and less code, the benefit of ViewState is often fewer trips to the database.

How ViewState Works

There''''s really nothing magical about ViewState. It''''s a hidden form field managed by the ASP.NET page framework. When ASP.NET executes a page, the ViewState values from the page and all of the controls are collected and formatted into a single encoded string, and then assigned to the value attribute of the hidden form field (specifically, <input type=hidden>). Since the hidden form field is part of the page sent to the client, the ViewState value is temporarily stored in the client''''s browser. If the client chooses to post the page back to the server, the ViewState string is posted back too. You can actually see the ViewState form field and its postback value in Figure 2 above.

Upon postback, the ASP.NET page framework parses the ViewState string and populates the ViewState properties for the page and each of the controls. The controls, in turn, use the ViewState data to rehydrate themselves to their former state.

There are three more small, but useful things to know about ViewState.

  1. You must have a server-side form tag (<form runat=server>) in your ASPX page if you want to use ViewState. A form field is required so the hidden field that contains the ViewState information can post back to the server. And, it must be a server-side form so the ASP.NET page framework can add the hidden field when the page is executed on the server.
  2. The page itself saves 20 or so bytes of information into ViewState, which it uses to distribute PostBack data and ViewState values to the correct controls upon postback. So, even if ViewState is disabled for the page or application, you may see a few remaining bytes in ViewState.
  3. In cases where the page does not post back, you can eliminate ViewState from a page by omitting the server side <form> tag.

Getting More from ViewState

ViewState is a marvelous way to track the state of a control across postbacks since it doesn''''t use server resources, doesn''''t time out, and works with any browser. If you are a control author, you''''ll definitely want to check out Maintaining State in a Control.

Page authors can also benefit from ViewState in much the same way. Occasionally your pages will contain UI state values that aren''''t stored by a control. You can track values in ViewState using a programming syntax is similar to that for Session and Cache:

[Visual Basic]

'''' save in ViewState 
ViewState("SortOrder") = "DESC"

'''' read from ViewState 
Dim SortOrder As String = CStr(ViewState("SortOrder"))

[C#]

// save in ViewState 
ViewState["SortOrder"] = "DESC";

// read from ViewState 
string sortOrder = (string)ViewState["SortOrder"];

Consider this example: you want to display a list of items in a Web page, and each user wants to sort the list differently. The list of items is static, so the pages can each bind to the same cached set of data, but the sort order is a small bit of user-specific UI state. ViewState is a great place to store this type of value. Here''''s the code:

[Visual Basic]

<%@ Import Namespace="System.Data" %>
<HTML>
    <HEAD>
        <title>ViewState for Page UI State Values</title>
    </HEAD>
    <body>
        <form runat="server">
            <H3>
                Storing Non-Control State in ViewState
            </H3>
            <P>
                This example stores the current sort order for a static 
                list of data in ViewState.<br>
                Click the link in the column header to sort the data by that field.<br>
                Click the link a second time to reverse the sort direction.
                <br><br><br>
                <asp:datagrid id="DataGrid1" runat="server" 
OnSortCommand="SortGrid" BorderStyle="None" BorderWidth="1px" 
BorderColor="#CCCCCC" BackColor="White" CellPadding="5" AllowSorting="True">
                    <HeaderStyle Font-Bold="True" ForeColor="White" 
BackColor="#006699">
                    </HeaderStyle>
                </asp:datagrid>
            </P>
        </form>
    </body>
</HTML>
<script runat="server">

    '''' SortField property is tracked in ViewState
    Property SortField() As String

        Get
            Dim o As Object = ViewState("SortField")
            If o Is Nothing Then
                Return String.Empty
            End If
            Return CStr(o)
        End Get

        Set(Value As String)
            If Value = SortField Then
                '''' same as current sort file, toggle sort direction
                SortAscending = Not SortAscending
            End If
            ViewState("SortField") = Value
        End Set

    End Property

    '''' SortAscending property is tracked in ViewState
    Property SortAscending() As Boolean

        Get
            Dim o As Object = ViewState("SortAscending")
            If o Is Nothing Then
                Return True
            End If
            Return CBool(o)
        End Get

        Set(Value As Boolean)
            ViewState("SortAscending") = Value
        End Set

    End Property

    Private Sub Page_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        If Not Page.IsPostBack Then
            BindGrid()
        End If

    End Sub

    Sub BindGrid()

        '''' Get data
        Dim ds As New DataSet()
        ds.ReadXml(Server.MapPath("TestData.xml"))
        
        Dim dv As New DataView(ds.Tables(0))

        '''' Apply sort filter and direction
        dv.Sort = SortField
        If Not SortAscending Then
            dv.Sort += " DESC"
        End If

        '''' Bind grid
        DataGrid1.DataSource = dv
        DataGrid1.DataBind()

    End Sub
    
    Private Sub SortGrid(sender As Object, e As DataGridSortCommandEventArgs)
        DataGrid1.CurrentPageIndex = 0
        SortField = e.SortExpression
        BindGrid()
    End Sub
    
</script>

[C#]

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<HTML>
    <HEAD>
        <title>ViewState for Page UI State Values</title>
    </HEAD>
    <body>
        <form runat="server">
            <H3>
                Storing Non-Control State in ViewState
            </H3>
            <P>
                This example stores the curr

[1] [2] [3] [4]  下一页

打印本文 打印本文 关闭窗口 关闭窗口