首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

ViewState 機制深度解析(二):Pair 樹狀儲存結構與 Control 類別處理流程

     編輯:關於.NET

前言

本系列第二部分揭示 ViewState 在伺服器端的樹狀儲存結構(Pair 遞迴結構),以及 Control 類別如何遞迴載入、儲存、追蹤整個控件樹的狀態。

一、 Pair 類別與 ViewState 樹狀結構

Pair 只有兩個欄位 First、Second,透過遞迴構成樹狀結構:

  • First:儲存當前控件的 ViewState(ArrayList 格式)。
  • Second:儲存子控件集合(ArrayList,交替存放 ID/索引與子控件的 Pair)。

根節點為 Page 的 savedState(Pair),完整保存整頁控件樹的層級關係與狀態資料。

二、 Control 類別核心方法解析

1. ViewState 屬性

定義於 Control:protected virtual StateBag ViewState { get; }。所有伺服器控件、Page 繼承此屬性。控件屬性(如 Button.Text)實際讀寫 ViewState["Text"],透過 StateBag 實現跨 PostBack 記憶。

2. LoadViewStateByID

決定子控件載入方式:true 依 ID 查找(延遲建立子控件時需用),false 依索引(預設,效能較好)。

3. EnableViewState

控制該控件及其子樹是否參與 ViewState 機制。

4. LoadViewStateRecursive(object savedState)

Page.LoadAllState 呼叫入口。遞迴流程:

  1. 若 EnableViewState,呼叫 LoadViewState(savedState.First) 載入自身狀態。
  2. 依 LoadViewStateByID 分派子控件狀態:
    • ByID:LoadChildViewStateByID(savedState.Second),遍歷 ID 陣列,FindControl(id).LoadViewStateRecursive(childPair)。
    • ByIndex:LoadChildViewStateByIndex(savedState.Second),遍歷索引陣列,Controls[index].LoadViewStateRecursive(childPair)。

5. SaveViewStateRecursive()

Page.SaveAllState 呼叫入口。遞迴流程:

  1. 呼叫 SaveViewState() 取得自身狀態 x(ArrayList)。
  2. 遍歷子控件集合,遞迴呼叫 SaveViewStateRecursive() 取得 z(ArrayList,格式:ID/索引 + 子 Pair)。
  3. 回傳 new Pair(x, z)。

6. TrackViewState

在 Control.InitRecursive 中遞迴呼叫,進而呼叫 ViewState.TrackViewState() 設定 marked=true,啟動狀態追蹤。

三、 關鍵流程圖解

Page.LoadAllState
  └─ Page.LoadPageStateFromPersistenceMedium → HiddenFieldPageStatePersister.Load → ObjectStateFormatter.Deserialize → Pair (savedState)
  └─ Control.LoadViewStateRecursive(savedState) → 遞迴載入全樹 ViewState

Page.SaveAllState
  └─ Control.SaveViewStateRecursive() → 遞迴收集全樹 ViewState → Pair (savedState)
  └─ Page.SavePageStateToPersistenceMedium → HiddenFieldPageStatePersister.Save → ObjectStateFormatter.Serialize → Base64 字串
  └─ Render 階段寫入 __VIEWSTATE 隱藏欄位

結語

Pair 遞迴結構完美映射控件樹層級,Control 類別透過 LoadViewStateRecursive/SaveViewStateRecursive 實現整樹狀態的序列化與反序列化。理解此流程有助於診斷 ViewState 異常、實作自訂控件狀態管理、優化序列化效能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved