ViewState 是 ASP.NET 解決 HTTP 無狀態特性的核心機制,透過在頁面回傳間持久化控件狀態,賦予 Web Form「記憶」能力。本系列第一部分建立整體認知:基本工作模式、客戶端形態、伺服器端三大核心類別協作、頁面生命週期關鍵節點、序列化/反序列化完整流程。
針對同一個 Page 的多次請求,Page 實例每次請求結束即銷毀。ViewState 將必要狀態序列化為字串,夾帶在回傳表單中發送給客戶端;下次請求時客戶端攜帶返回,伺服器反序列化還原控件狀態。本質上是「客戶端儲存、伺服器還原」的狀態持久化模式。
HTML 中呈現為隱藏欄位:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwULLTE0MTAzNDUwNThkZKr77J2uy7fatyBou8PocG80X4Jt" />
Value 為 Pair 物件序列化 → Base64 編碼後的字串。可用 ViewStateDecoder 等工具解碼檢視。
ViewState 屬性、遞迴載入/儲存/追蹤邏輯。IsDirty 標記。協作流程:
__VIEWSTATE 為 Pair。Control.LoadViewStateRecursive 遞迴分發狀態至各控件的 ViewState。ViewState.Add 設定 IsDirty=true。Control.SaveViewStateRecursive 遞迴收集 IsDirty 項目。__VIEWSTATE 回傳客戶端。| 階段 | 方法 | ViewState 相關動作 |
|---|---|---|
| 初始化 | Control.InitRecursive | 遞迴呼叫 TrackViewState() → StateBag.marked=true 開啟追蹤 |
| 載入 | Page.LoadAllState (僅 PostBack) | LoadPageStateFromPersistenceMedium 反序列化 → LoadViewStateRecursive 分發 |
| 儲存 | Page.SaveAllState | SaveViewStateRecursive 收集 → SavePageStateToPersistenceMedium 序列化 |
| 渲染 | HtmlForm.RenderChildren → Page.RenderViewStateFields | 將序列化字串寫入 __VIEWSTATE 隱藏欄位 |
HiddenFieldPageStatePersister 使用 ObjectStateFormatter:
MemoryStream 序列化物件圖。buf。MachineKeySection.EncryptOrDecryptData(true, buf...)。MachineKeySection.GetEncodedData(buf...) 附加 SHA1/MD5 雜湊。Convert.ToBase64String 輸出字串。Convert.FromBase64String 解碼位元組陣列。EncryptOrDecryptData(false, buf...) 解密。GetDecodedData 驗證雜湊,失敗拋例外。MemoryStream 反序列化回 Pair 物件。ViewState 以 Pair 樹狀結構映射控件樹,透過 StateBag.IsDirty 精準追蹤變更,配合 ObjectStateFormatter 的加密/簽名機制,在客戶端與伺服器間安全、高效地傳遞狀態。掌握生命週期節點與序列化管線,是進階 ASP.NET 開發與疑難排解的基石。