明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

ViewState初探

[摘要]ViewState 的工作原理ViewState是一種機(jī)制,ASP.NET 使用這種機(jī)制來跟蹤服務(wù)器控件狀態(tài)值,否則這些值將不作為 HTTP 窗體的一部分而回傳。例如,由 Label 控件顯示的文本默認(rèn)情況下就保存在 ViewState 中。作為開發(fā)人員,您可以綁定數(shù)據(jù),或在首次加載該頁面時僅對 ...

ViewState 的工作原理
ViewState是一種機(jī)制,ASP.NET 使用這種機(jī)制來跟蹤服務(wù)器控件狀態(tài)值,否則這些值將不作為 HTTP 窗體的一部分而回傳。例如,由 Label 控件顯示的文本默認(rèn)情況下就保存在 ViewState 中。作為開發(fā)人員,您可以綁定數(shù)據(jù),或在首次加載該頁面時僅對 Label 編程設(shè)置一次,在后續(xù)的回傳中,該標(biāo)簽文本將自動從 ViewState 中重新填充。因此,除了可以減少繁瑣的工作和代碼外,ViewState 通常還可以減少數(shù)據(jù)庫的往返次數(shù)。
ViewState 確實沒有什么神秘之處,它是由 ASP.NET 頁面框架管理的一個隱藏的窗體字段。當(dāng) ASP.NET 執(zhí)行某個頁面時,該頁面上的 ViewState 值和所有控件將被收集并格式化成一個編碼字符串,然后被分配給隱藏窗體字段的值屬性(即 <input type=hidden>)。由于隱藏窗體字段是發(fā)送到客戶端的頁面的一部分,所以 ViewState 值被臨時存儲在客戶端的瀏覽器中。如果客戶端選擇將該頁面回傳給服務(wù)器,則 ViewState 字符串也將被回傳。在上面的圖 2 中可以看到 ViewState 窗體字段及其回傳的值。
回傳后,ASP.NET 頁面框架將解析 ViewState 字符串,并為該頁面和各個控件填充 ViewState 屬性。然后,控件再使用 ViewState 數(shù)據(jù)將自己重新恢復(fù)為以前的狀態(tài)。



關(guān)于 ViewState 還有三個值得注意的小問題。
如果要使用 ViewState,則在 ASPX 頁面中必須有一個服務(wù)器端窗體標(biāo)記 (<form runat=server>)。窗體字段是必需的,這樣包含 ViewState 信息的隱藏字段才能回傳給服務(wù)器。而且,該窗體還必須是服務(wù)器端的窗體,這樣在服務(wù)器上執(zhí)行該頁面時,ASP.NET 頁面框架才能添加隱藏的字段。 
頁面本身將 20 字節(jié)左右的信息保存在 ViewState 中,用于在回傳時將 PostBack 數(shù)據(jù)和 ViewState 值分發(fā)給正確的控件。因此,即使該頁面或應(yīng)用程序禁用了 ViewState,仍可以在 ViewState 中看到少量的剩余字節(jié)。 
在頁面不回傳的情況下,可以通過省略服務(wù)器端的 <form> 標(biāo)記來去除頁面中的 ViewState。 



充分利用 ViewState
ViewState 為跨回傳跟蹤控件的狀態(tài)提供了一條神奇的途徑,因為它不使用服務(wù)器資源、不會超時,并且適用于任何瀏覽器。如果您要編寫控件,那么肯定需要了解如何在控件中維護(hù)狀態(tài)(英文)。
開發(fā)人員在編寫頁面時同樣可以按照幾乎相同的方式來利用 ViewState,只是有時頁面會包含不由控件存儲的 UI 狀態(tài)值。您可以跟蹤 ViewState 中的值,使用的編程語法與會話和高速緩存的語法類似:
請看下面的示例:要在 Web 頁上顯示一個項目列表,而每個用戶需要不同的列表排序。項目列表是靜態(tài)的,因此可以將這些頁面綁定到相同的緩存數(shù)據(jù)集,而排序順序只是用戶特定的 UI 狀態(tài)的一小部分。ViewState 非常適合于存儲這種類型的值。代碼如下:



<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<HTML>
    <HEAD>
        <title>用于頁面 UI 狀態(tài)值的 ViewState</title>
    </HEAD>
    <body>
        <form runat="server">
            <H3>
                在 ViewState 中存儲非控件狀態(tài)
            </H3>
            <P>
                此示例將一列靜態(tài)數(shù)據(jù)的當(dāng)前排序順序存儲在 ViewState 中。<br>
                單擊列標(biāo)題中的鏈接,可按該字段排序數(shù)據(jù)。<br>
                再次單擊該鏈接,將按相反順序排序。
                <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">



    // 在 ViewState 中跟蹤 SortField 屬性
    string SortField {



        get {
            object o = ViewState["SortField"];
            if (o == null) {
                return String.Empty;
            }
            return (string)o;
        }



        set {
            if (value == SortField) {
                // 與當(dāng)前排序文件相同,切換排序方向
                SortAscending = !SortAscending;
            }
            ViewState["SortField"] = value;
        }
    }



    // 在 ViewState 中跟蹤 SortAscending 屬性
    bool SortAscending {



        get {
            object o = ViewState["SortAscending"];
            if (o == null) {
                return true;
            }
            return (bool)o;
        }



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



    void Page_Load(object sender, EventArgs e) {



        if (!Page.IsPostBack) {
            BindGrid();
        }
    }



    void BindGrid() {



        // 獲取數(shù)據(jù)
        DataSet ds = new DataSet();
        ds.ReadXml(Server.MapPath("TestData.xml"));
        
        DataView dv = new DataView(ds.Tables[0]);



        // 應(yīng)用排序過濾器和方向
        dv.Sort = SortField;
        if (!SortAscending) {
            dv.Sort += " DESC";
        }



        // 綁定網(wǎng)格
        DataGrid1.DataSource = dv;
        DataGrid1.DataBind();
   }



   void SortGrid(object sender, DataGridSortCommandEventArgs e) {



        DataGrid1.CurrentPageIndex = 0;
        SortField = e.SortExpression;
        BindGrid();
    }



</script>



下面是上述代碼段中引用的 testdata.xml 的代碼:



<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <Table>
    <pub_id>0736</pub_id>
    <pub_name>New Moon Books</pub_name>
    <city>Boston</city>
    <state>MA</state>
    <country>USA</country>
  </Table>
  <Table>
    <pub_id>0877</pub_id>
    <pub_name>Binnet &amp; Hardley</pub_name>
    <city>Washington</city>
    <state>DC</state>
    <country>USA</country>
  </Table>
  <Table>
    <pub_id>1389</pub_id>
    <pub_name>Algodata Infosystems</pub_name>
    <city>Berkeley</city>
    <state>CA</state>
    <country>USA</country>
  </Table>
  <Table>
    <pub_id>1622</pub_id>
    <pub_name>Five Lakes Publishing</pub_name>
    <city>Chicago</city>
    <state>IL</state>
    <country>USA</country>
  </Table>
  <Table>
    <pub_id>1756</pub_id>
    <pub_name>Ramona Publishers</pub_name>
    <city>Dallas</city>
    <state>TX</state>
    <country>USA</country>
  </Table>
  <Table>
    <pub_id>9901</pub_id>
    <pub_name>GGG&amp;G</pub_name>
    <city>Muenchen</city>
    <country>Germany</country>
  </Table>
  <Table>
    <pub_id>9952</pub_id>
    <pub_name>Scootney Books</pub_name>
    <city>New York</city>
    <state>NY</state>
    <country>USA</country>
  </Table>
  <Table>
    <pub_id>9999</pub_id>
    <pub_name>Lucerne Publishing</pub_name>
    <city>Paris</city>
    <country>France</country>
  </Table>
</NewDataSet>



標(biāo)簽:ViewState初探