ViewState 是 ASP.NET Web Forms 維持控件狀態的機制,將控件屬性值序列化為 Base64 字符串存放在隱藏字段 __VIEWSTATE 中。缺點:
對於純展示頁面、只讀列表、高性能要求場景,應盡量禁用。
<asp:GridView ID="gvList" runat="server" EnableViewState="false" />
<asp:Label ID="lblStatic" runat="server" EnableViewState="false" Text="固定文本" />
適用:不需回發保持狀態的控件(只讀標籤、純展示 GridView、Repeater、靜態圖片)。
<%@ Page Language="C#" EnableViewState="false" %>
效果:頁面及所有子控件默認 EnableViewState="false",單個控件可顯式設置 EnableViewState="true" 覆蓋。
<configuration>
<system.web>
<pages enableViewState="false" />
</system.web>
</configuration>
優先級:控件級 > 頁面級 > 應用級。即控件顯式設置始終生效。
// 頁面中臨時添加,檢查渲染輸出
protected override void Render(HtmlTextWriter writer)
{
var viewStateField = Page.ClientScript.GetType().GetField("_viewStateField",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
// 或者直接查看頁面源碼搜索 __VIEWSTATE
base.Render(writer);
}
瀏覽器開發工具 → Network → 頁面請求 → Response Body 搜索 __VIEWSTATE,若無或極短(如 /wEPDw== 空 ViewState),說明已生效。
| 誤區 | 真相 | 正確做法 |
|---|---|---|
| 禁用後控件值丟失 | 只有回發時需保持的狀態才丟失,初次綁定值不受影響 | 按鈕點擊後重新綁定數據源,或啟用該控件 ViewState |
| GridView 分頁/排序失效 | 分頁/排序依賴 ViewState 保存 PageIndex/SortExpression | GridView 必須啟用 ViewState,或手工在 Session/ViewState 保存分頁狀態 |
| 動態創建控件消失 | 動態控件每次請求必須重建,ViewState 只保存屬性值 | 在 Page_Init 重建動態控件,並確保 ID 一致 |
| ControlState 也被禁用 | EnableViewState 不影響 ControlState (如 GridView 分頁核心邏輯) | 無需額外操作,ControlState 由框架自動管理 |
web.config 設置 enableViewState="false" 作為項目基線。EnableViewState="true"。<pages viewStateEncryptionMode="Always" /> 或 ViewStateMac 防篡改。| 架構 | 狀態管理 | ViewState 等價物 |
|---|---|---|
| ASP.NET Core MVC / Razor Pages | 無狀態,每請求重建模型 | Model Binding + TempData / Session |
| Blazor Server | 服務端組件樹狀態 | Circuit 內存狀態,無隱藏字段 |
| Blazor WebAssembly | 客戶端內存狀態 | 瀏覽器內存,無網絡傳輸 |
| 前後端分離 (React/Vue + WebAPI) | 客戶端狀態管理 | Redux/Vuex/Pinia / LocalStorage |
合理禁用 ViewState 是 Web Forms 性能優化的「第一把手術刀」,配合 EnableViewStateMac、ViewStateEncryptionMode,可在兼容舊業務的前提下大幅降低頁面負載。