本系列第三部分深入剖析 StateBag 內部實作、ControlState 差異、ViewState 優缺點與安全性、壓縮與儲存位置優化方案。
StateBag 實作 IStateManager、IDictionary,是具備狀態追蹤能力的字典。內部將 Value 包裝為 StateItem:
public sealed class StateItem
{
internal StateItem(object initialValue);
public bool IsDirty { get; set; } // 標記是否被修改
public object Value { get; set; }
}
marked=true(已呼叫 TrackViewState),設定 IsDirty=true。ArrayList(Key/Value 交替),呼叫 Add 還原。此時所有項目 IsDirty=true。IsDirty=true 的項目至 ArrayList 回傳。marked=true,啟動狀態追蹤。結論:只要屬性曾被修改(即使後續恢復原值),IsDirty 永遠為 true,導致每次 PostBack 都序列化該項目。
| 特性 | ViewState | ControlState |
|---|---|---|
| 可停用 | 是(EnableViewState=false) | 否(不可停用) |
| 實作方式 | 框架自動管理 | 開發者手動實作 |
| 儲存位置 | __VIEWSTATE 隱藏欄位 | 同 __VIEWSTATE(序列化在一起) |
| 啟用條件 | 預設開啟 | 需在 OnInit 呼叫 RegisterRequiresControlState |
| 適用場景 | 一般屬性保持 | 關鍵資料(如 GridView 分頁索引)必須保持 |
ControlState 需重寫 SaveControlState、LoadControlState 自定序列化邏輯。
EnableViewStateMAC=true(預設開啟),SHA1/MD5 雜湊防竄改。ViewStateEncryptionMode=Always 或呼叫 RegisterRequiresViewStateEncryption 啟用 AES 加密。Page_Init 設定唯一使用者金鑰,防 CSRF 攻擊。<asp:GridView EnableViewState="false" /><%@ Page EnableViewState="False" %><pages enableViewState="false" /> in web.config理解 StateBag 的 IsDirty 機制、區分 ViewState/ControlState 職責、依場景啟用安全性與優化手段,是構建高效能、安全 ASP.NET 應用的關鍵。