與剛接觸 ASP
NET 頁面的開發人員交談時
他們通常向我提出的第一個問題就是
那個 ViewState 到底是什麼?
他們的語氣中流露出的那種感覺
就象我來到一家異國情調的餐館
侍者端上一道我從未見過的菜肴時的那種感覺
既疑惑不解
又充滿好奇
但肯定有人認為它不錯
否則就不會提供了
所以
我會先嘗一嘗
或許會喜歡上它
盡管它看上去的確很古怪!
對於 ViewState 也是如此
但是如果適應了它的風格
您會發現在許多情況下
您將樂於在自己的 ASP
NET 應用程序中使用 ViewState
因為它可以幫助您使用更少的代碼完成更多的工作
但是
有時也會對 ViewState 完全棄之不用
下面我們就這兩種情況分別進行闡述
不過
讓我們先回答什麼是 ViewState 這個問題
答案
ViewState 用於維護頁面的 UI 狀態
Web 是沒有狀態的
ASP
NET 頁面也沒有狀態
它們在到服務器的每個往返過程中被實例化
執行
呈現和處理
作為 Web 開發人員
您可以使用眾所周知的技術(如以會話狀態將狀態存儲在服務器上
或將頁面回傳到自身)來添加狀態
下面我們以圖
中的注冊窗體為例進行論述
圖
恢復回傳的窗體值
從上圖中可以看出
我為便餐選擇了一個無效的值
此窗體與 Web 上的多數窗體一樣友好
它在出現錯誤的字段旁邊顯示一條有用的錯誤消息和一個星號
而且
窗體中還顯示了我在其他文本框和下拉列表中輸入的所有有效值
這在某種程度上是可能的
因為 HTML 窗體元素會在 HTTP 標頭中將其當前值從浏覽器發送到服務器
您可以使用 ASP
NET 跟蹤來查看回傳的窗體值
如圖
所示
圖
HTTP 窗體中回傳的值(通過 ASP
NET 跟蹤顯示)
在 ASP
NET 之前
通過多次回傳將值恢復到窗體字段中完全是頁面開發人員的責任
他們將不得不從 HTTP 窗體中逐個拾取回傳值
然後再將其推回字段中
幸運的是
現在 ASP
NET 可以自動完成這項任務
從而為開發人員免除了一項令人厭煩的工作
同時也無需再為窗體編寫大量的代碼
但這並不是 ViewState
ViewState(英文)是一種機制
ASP
NET 使用這種機制來跟蹤服務器控件狀態值
否則這些值將不作為 HTTP 窗體的一部分而回傳
例如
由 Label 控件顯示的文本默認情況下就保存在 ViewState 中
作為開發人員
您可以綁定數據
或在首次加載該頁面時僅對 Label 編程設置一次
在後續的回傳中
該標簽文本將自動從 ViewState 中重新填充
因此
除了可以減少繁瑣的工作和代碼外
ViewState 通常還可以減少數據庫的往返次數
ViewState 的工作原理
ViewState 確實沒有什麼神秘之處
它是由 ASP
NET 頁面框架管理的一個隱藏的窗體字段
當 ASP
NET 執行某個頁面時
該頁面上的 ViewState 值和所有控件將被收集並格式化成一個編碼字符串
然後被分配給隱藏窗體字段的值屬性(即 <input type=hidden>)
由於隱藏窗體字段是發送到客戶端的頁面的一部分
所以 ViewState 值被臨時存儲在客戶端的浏覽器中
如果客戶端選擇將該頁面回傳給服務器
則 ViewState 字符串也將被回傳
在上面的圖
中可以看到 ViewState 窗體字段及其回傳的值
回傳後
ASP
NET 頁面框架將解析 ViewState 字符串
並為該頁面和各個控件填充 ViewState 屬性
然後
控件再使用 ViewState 數據將自己重新恢復為以前的狀態
關於 ViewState 還有三個值得注意的小問題
如果要使用 ViewState
則在 ASPX 頁面中必須有一個服務器端窗體標記 (<form runat=server>)
窗體字段是必需的
這樣包含 ViewState 信息的隱藏字段才能回傳給服務器
而且
該窗體還必須是服務器端的窗體
這樣在服務器上執行該頁面時
ASP
NET 頁面框架才能添加隱藏的字段
頁面本身將
字節左右的信息保存在 ViewState 中
用於在回傳時將 PostBack 數據和 ViewState 值分發給正確的控件
因此
即使該頁面或應用程序禁用了 ViewState
仍可以在 ViewState 中看到少量的剩余字節
在頁面不回傳的情況下
可以通過省略服務器端的 <form> 標記來去除頁面中的 ViewState
充分利用 ViewState
ViewState 為跨回傳跟蹤控件的狀態提供了一條神奇的途徑
因為它不使用服務器資源
不會超時
並且適用於任何浏覽器
如果您要編寫控件
那麼肯定需要了解如何在控件中維護狀態(英文)
開發人員在編寫頁面時同樣可以按照幾乎相同的方式來利用 ViewState
只是有時頁面會包含不由控件存儲的 UI 狀態值
您可以跟蹤 ViewState 中的值
使用的編程語法與會話和高速緩存的語法類似
[Visual Basic]
保存在 ViewState 中
ViewState(
SortOrder
) =
DESC
從 ViewState 中讀取
Dim SortOrder As String = CStr(ViewState(
SortOrder
))
[C#]
// 保存在 ViewState 中
ViewState[
SortOrder
] =
DESC
;
// 從 ViewState 中讀取
string sortOrder = (string)ViewState[
SortOrder
];
From:http://tw.wingwit.com/Article/program/net/201311/13322.html