共用方式為


控制檢視狀態

更新:2007 年 11 月

Microsoft ASP.NET Web 網頁能在往返期間維護本身的檢視狀態。在設定控制項的屬性時,ASP.NET 會將屬性值儲存為控制項狀態的一部分。這對應用程式而言,看起來像是網頁的存留期 (Lifetime) 橫跨了多個用戶端要求。這個頁面層級狀態即稱為網頁的檢視狀態。

在一般的 ASP.NET Web 網頁上,伺服器會將檢視狀態當做表單中的隱藏欄位,並傳送做為對用戶端之回應的一部分,而且用戶端會將它傳回給伺服器做為回傳的一部分。然而,為了在使用行動控制項時降低頻寬需求,ASP.NET 不會傳送網頁的檢視狀態給用戶端。反而,檢視狀態會在伺服器上儲存為使用者工作階段 (Session) 的一部分。只要有檢視狀態,ASP.NET 便會將識別此網頁檢視狀態的隱藏欄位當做對用戶端之每個回應的一部分進行傳送,而且用戶端會將此隱藏欄位當做下次回傳給伺服器的一部分。

管理檢視狀態記錄

由於特定頁面的檢視狀態都必須保存在該伺服器上,因此如果使用者按一下瀏覽器的 [上一頁] 按鈕,伺服器上的目前狀態可能就不會與瀏覽器上的目前頁面保持同步。例如,假設使用者移至網頁 1,接著按一下按鈕移至網頁 2,然後再按下 [上一頁] 返回網頁 1。瀏覽器上的目前網頁便會是網頁 1,但伺服器上的目前狀態則是會網頁 2。

為了要解決這個問題,ASP.NET Mobile Web 網頁會在使用者工作階段中維護檢視狀態資訊的記錄。傳送至用戶端的每一個識別項都將對應至這個記錄中的位置。在先前的範例中,如果使用者再度從網頁 1 張貼,Mobile Web 網頁便會使用在網頁 1 儲存的識別項來同步處理檢視狀態記錄。

您可以設定此記錄的大小,針對應用程式加以微調。預設大小為 6,而且可以藉由將數值屬性 (Attribute) 加入至 Web.config 檔的標記 (Tag) 而予以變更,如下列範例所示:

<configuration>
  <system.web>
    <mobileControls sessionStateHistorySize="10" />
  </system.web>
</configuration>

管理逾期的工作階段

因為檢視狀態儲存在使用者的工作階段中,如果網頁沒有在工作階段期限內回傳,檢視狀態可能會過期。這個期限對 Mobile Web 網頁是唯一的。當使用者回傳沒有可用檢視狀態的網頁時,便會呼叫網頁的 OnViewStateExpire 方法。這個方法的預設實作 (Implementation) 會擲回例外狀況 (Exception),表示檢視狀態已經逾期。然而,如果應用程式能夠在逾期之後手動還原檢視狀態,您就能在頁面層級覆寫這個方法,以及選擇不要呼叫基底實作。

啟用和停用檢視狀態

使用工作階段管理檢視狀態的優點是可以產生較小的回應大小。缺點則是工作階段狀態的無效率使用可能會導致不良的效能。如果您使用包含大量資料的控制項,您可以使用自訂重新編頁或停用檢視狀態等技巧來提高效率。例如,假設有一個顯示新聞話題的網站。與其儲存每個使用者工作階段的文章內容,該網站可以使用更聰明的資料存取方式,以便在伺服器上只快取每篇文章的一份複本,這樣就可以將工作階段狀態的使用量降到最低。

若要停用控制項及其子控制項的檢視狀態,請將控制項的 EnableViewState 屬性設定為 false。若要停用整個網頁的檢視狀態,請將 @ Page 指示詞的 EnableViewState 屬性 (Attribute) 設定為 false。

即使在檢視狀態停用時,有些行動控制項會儲存往返用戶端過程之間的基本狀態資訊。這類資訊的範例包括網頁上目前使用中的表單。當您關閉檢視狀態時,網頁會將這個基本資訊另存為隱藏的表單變數,該變數會在往返過程中傳送給用戶端。

根據預設,ASP.NET 的工作階段管理功能需要伺服器將工作階段 Cookie 寫入至用戶端。用戶端隨後會對工作階段期間的每個要求送出 Cookie,伺服器則會使用 Cookie 資訊查詢工作階段狀態資訊。然而,有許多行動裝置並不支援 Cookie。為了使工作階段管理 (包括檢視狀態) 可以在這些裝置上正確運作,您必須設定應用程式使用 Cookieless 的工作階段管理。如果啟用這個功能,ASP.NET 會在應用程式 URL 中自動插入工作階段金鑰。

有些裝置不支援 Cookie。若要保存長期的用戶端狀態,應用程式可以使用用戶端的特定資訊,例如使用者所輸入的客戶號碼。因為您不能指望用戶端擁有 Cookie,應用程式必須將您帶到可以標記書籤的替代網頁。下列程式碼會示範一個範例。瀏覽至這個 URL 的使用者將檢視需在其中輸入其客戶代碼的表單。應用程式接著顯示替代 URL,使用者可以將之標記為書籤。

<%@ Page Inherits="System.Web.UI.MobileControls.MobilePage"
    Language="C#"
    EnableViewState="false" %>

<script  language="c#">
protected void Page_Load(Object sender, EventArgs e)
{
    String customerID = Request.QueryString["cid"];

    if (customerID != null)
    {
        // A customer ID was found. Simulate a lookup by 
        // converting the client ID back to a user.
        int underscore = customerID.IndexOf('_');
        if (underscore != -1)
        {
            // If visiting the first time, prompt the user to bookmark.
            if (Session["FirstTime"] != null)
            {
                Session["FirstTime"] = null;
                WelcomeLabel.Text = String.Format("Welcome, {0}", 
                customerID.Substring(0, underscore));
                ActiveForm = WelcomeForm;
            }
            else
            {
                ReturnLabel.Text = String.Format("Welcome back, {0}", 
                    customerID.Substring(0, underscore));
                ActiveForm = ReturnForm;
            }
        }
    }
}

protected void LoginForm_OnSubmit(Object sender, EventArgs e)
{
    // Generate a customer ID. Normally, you would create
    // a new customer profile.
    String customerID = CustomerName.Text + "_" + 
        System.Guid.NewGuid().ToString();
    String path = AbsoluteFilePath + "?cid=" + 
        Server.UrlEncode(customerID);
    Session["FirstTime"] = true;
    RedirectToMobilePage(path);
}
</script>

<mobile:Form >
  <mobile:Label  StyleReference="title">
    Welcome to the site. Please register to continue.
  </mobile:Label>
  <mobile:TextBox  id="CustomerName" />
  <mobile:Command  OnClick="LoginForm_OnSubmit" 
    Text="Register" />
</mobile:Form>

<mobile:Form id="WelcomeForm" >
  <mobile:Label  id="WelcomeLabel" />
    Please bookmark this page for future access.
</mobile:Form>

<mobile:Form id="ReturnForm" >
  <mobile:Label  id="ReturnLabel" />
</mobile:Form>

最佳化行動應用程式的檢視狀態

對 Mobile Web 網頁而言,下列考量非常重要:

  • 將檢視狀態儲存至工作階段已高度最佳化。如果沒有任何要儲存的檢視狀態,工作階段中就不會儲存任何資料,因此也不會有任何識別項會傳送至用戶端。然而,想要避免使用工作階段管理,或想要網頁具有高速傳輸的能力的應用程式開發人員可以考慮降低或排除檢視狀態的使用。在許多應用程式案例 (例如呈現格式化文字的網頁) 中,檢視狀態是沒有必要的,而且最好要關閉。

  • 除了應用程式檢視狀態,Mobile Web 網頁也必須存放有關網頁的其他類型狀態資訊。這項資訊可能包括作用中的表單,或是與表單相關的重新編頁資訊。這類資訊永遠會傳送至用戶端,而非保存在伺服器上,並且通常會以最佳化方式產生。例如,如果第一個表單是使用中的,或表單的第一頁正在顯示,這個資訊不會儲存,因為這些是預設狀態。這類狀態資訊即稱為私用檢視狀態。所有控制項都可以覆寫 LoadPrivateViewStateSavePrivateViewState 方法,以便讀取並寫入私用檢視狀態。

    注意事項:

    如果您在工作階段狀態中包含機密資訊,就必須透過 HTTPS 和 SSL/TLS 驗證進行連線,才能算是良好的安全性措施。

請參閱

概念

ASP.NET 狀態管理概觀

控制工作階段狀態

參考

LoadPrivateViewState

SavePrivateViewState

其他資源

支援檢視狀態

建立 ASP.NET Mobile Web 網頁

應用程式開發人員手冊

開發 ASP.NET Mobile Web 網頁