檢視狀態管理是一種簡單且方便的技術。通過檢視狀態管理,控制項開發人員可以在一個原本無狀態的環境下類比有狀態的且看起來是持續執行的運行效果。其具體過程為:每當使用者請求某個.aspx頁面時,.NET架構首先把相關控制項的狀態序列化成一個字串,然後將其作為名為__VIEWSTATE的隱藏欄位的Value值發送到用戶端。如果頁面是第一次被請求,那麼伺服器控制項也將是被第一次執行,名為__VIEWSTATE的隱藏欄位中只包含控制項的預設資訊,通常為空白或者null。在隨後的回送事件中,ViewState中就儲存了伺服器控制項在簽名回送中可用的屬性狀態。這樣伺服器控制項就可以監視在當前被處理的回送事件發生之前的狀態了。這些過程是由.NET架構負責的,對使用者來說,執行.aspx頁面就有了持續執行的效果。
最常見的檢視狀態管理的方法是應用伺服器控制項的ViewState屬性。ViewState是Syetem.Web.UI.StateBag類型,即一個鍵/值對的字典,伺服器控制項的屬性值可以儲存在ViewState中。
public String Text
{
get
{
return (String)ViewState["Text"];
}
set
{
ViewState["Text"] = value;
}
}
通過set訪問器,將屬性Text的值寫入ViewState["Text"]對象中;通過get訪問器,從對象ViewState["Text"]中擷取屬性值。這就是檢視狀態處理最簡單的方法。在這個過程中的TrackViewState、SaveViewState、LoadViewState等檢視狀態管理過程都是由.NET架構自動完成的。
預設情況下,ViewState只能儲存少數資料類型,它們是String、Int、Bool、Array、ArrayList、HashTable等。如果屬性儲存區的是其他資料類型,則必須編寫子定義的檢視狀態管理程式。
另外,使用ViewState時,對象必須先序列化,然後再通過回傳進行還原序列化。因此,做為一個優秀的控制項開發人員必須瞭解有關ViewState效能的內容。預設情況下,控制項的ViewState將被啟用,如果不需要使用ViewState,最好還是將它關閉。以下情況將不再需要ViewState:控制項未定義伺服器端事件(這時的控制項事件均為用戶端事件且不參加回送的);控制項沒有動態或資料繫結的屬性值。其關閉ViewState的方法是將控制項的EnableViewState的值設定為“false”,即EnableViewState="false"。
最後,還需要瞭解一些有關檢視狀態安全性方面的內容。當查看__VIEWSTATE隱藏欄位時,看到的只是一些沒有意義的字串。這是.NET架構通過Base64位編碼對相關內容編碼的結果,預設情況下它們是通過明文方式在用戶端和伺服器端之間往返傳送。在某些情況下,例如涉及密碼、帳號、連接字串等敏感內容時,使用預設是很不安全的,為此,.NET架構為ViewState提供了以下兩種安全機制。
- 校正機制:可以通過設定EnableViewStateMAC="true"屬性來指示.NET架構向ViewState資料中追加一個散列碼(該散列碼是一種SHA1類型,長度有160位,因此會嚴重影響執行效能)。在回傳事件發生時,將重建立立該散列碼,它必須和最初的散列碼匹配。通過這種方式,能夠有效檢驗ViewState在傳送過程中是否能夠被篡改。預設情況下,.NET架構使用SHA1演算法來產生ViewState散列代碼。此外,也可以通過在machine.config檔案中設定<machineKey>來選擇MD5演算法,例如<machineKey validation="MD5"/>。MD5演算法的效能要比SHA1演算法好一些,但是同樣不夠安全。
- 加密機制:使用加密來保護ViewState欄位中的實際資料值。首先,必須如上述設定EnableViewStateMAC="true"。然後,將machineKey validation類型設定為3DES,即<machineKey validationKey="AutoGenerate" decryptionKey="AutoGenerate" validation="3DES">,這指示ASP.NET使用3DES密碼編譯演算法來加密ViewState值。
以上是 檢視狀態管理概述——《ASP.NET伺服器控制項開發技術與執行個體》摘錄。
方案
檢視狀態由 ASP.NET 頁架構自動用於儲存在各個回傳之間必須保留的資訊。此資訊包括控制項的任何非預設值。
您還可以使用檢視狀態來儲存特定於頁的應用程式資料。
功能
檢視狀態是 ASP.NET 頁中的存放庫,可以儲存必須在回傳過程中保留的值。頁架構使用檢視狀態在各個回傳之間儲存控制項設定。
可以在您自己的應用程式中使用檢視狀態完成以下工作:
例如,您可以將資訊儲存在檢視狀態中,這樣在下次將該頁發送到伺服器時,代碼便可以在頁載入事件程序中訪問這些資訊。有關推薦的使用方法
背景
Web 應用程式是無狀態的。每次從伺服器請求頁時,都會建立網頁類的一個新執行個體。這通常意味著在每次往返過程中會丟失該頁及其控制項中的所有資訊。例如,預設狀態下,如果使用者將資訊輸入到 HTML 網頁上的文字框中,
該資訊會發送到伺服器。但是,該資訊不會在響應中返回到瀏覽器。
為了克服 Web 編程的這一固有的局限性,ASP.NET 頁架構套件含幾種狀態管理功能,可以在往返過程之間將頁和控制項值儲存到 Web 服務器。其中一種功能便是檢視狀態。
預設情況下,ASP.NET 頁架構使用檢視狀態在往返過程之間儲存頁和控制項值。在呈現頁的 HTML 時,必須在回傳過程中保留的頁和值的目前狀態將被序列化為 Base 64 編碼字串。然後,它們將被放入頁中的一個或多個隱藏欄位。
您可以在代碼中使用頁的 屬性訪問檢視狀態。 屬性是一個包含鍵/值對(其中包含檢視狀態資料)的字典。
代碼
前台代碼
<div> Label1: <asp:Label ID="Label1" runat="server" Text="取消了檢視狀態" EnableViewState="false"></asp:Label> <br /> <br /> Label2: <asp:Label ID="Label2" runat="server" Text="檢視狀態" EnableViewState="true"></asp:Label> <br /> <br /> <asp:Button ID="Button1" runat="server" Text="設定Label1,Label2的值為XXX" onclick="Button1_Click" /> <br /> <asp:Button ID="Button2" runat="server" Text="重新整理" /> </div>
後台代碼
protected void Button1_Click(object sender, EventArgs e) { Label1.Text = "XXX"; Label2.Text = "XXX"; }
執行頁面
注意Label1和Label2值的變化,由於Label2有檢視狀態所以在重新整理後並沒有變化。
頁面生命週期 是 先載入檢視狀態裡面的值,然後再響應頁面事件,所以第二步按鈕後都變成“XXX”了,但是此時label1中的檢視狀態的值並沒有改變,在按[重新整理] 按鈕後,Label1隻是載入了以前的檢視狀態值。