ASP.NET中的ViewState
ViewState是ASP.NET中用來儲存WEB控制項回傳時狀態值一種機制。在WEB表單(FORM)的設定為runat="server",這個表單(FORM)會被附加一個隱藏的屬性_VIEWSTATE。_VIEWSTATE中存放了所有控制項在ViewState中的狀態值。
ViewState是類Control中的一個域,其他所有控制項通過繼承Control來獲得了ViewState功能。它的類型是system.Web.UI.StateBag,一個名稱/值的對象集合。
當請求某個頁面時,ASP.NET把所有控制項的狀態序列化成一個字串,然後做為表單的隱藏屬性送到用戶端。當用戶端把頁面回傳時,ASP.NET分析回傳的表單內容,並賦給控制項對應的值。當然這些全部是由ASP.NET負責的,對使用者來說是透明的。
使用ViewState的條件
如果要使用 ViewState,則在 ASPX 頁面中必須有一個伺服器端表單標記 ()。表單欄位是必需的,這樣包含 ViewState 資訊的隱藏欄位才能回傳給伺服器。而且,該表單還必須是伺服器端的表單,這樣在伺服器上執行該頁面時,ASP.NET 頁面架構才能添加隱藏的欄位。
Page 的 EnableViewState 屬性值為 true。
控制項的 EnableViewState 屬性值為 true。
頁面本身將 20 位元組左右的資訊儲存在 ViewState 中,用於在回傳時將 PostBack 資料和 ViewState 值分發給正確的控制項。因此,即使該頁面或應用程式禁用了 ViewState,仍可以在 ViewState 中看到少量的剩餘位元組。
設定ViewState
ViewState可以在控制項,頁,程式,全域配置中設定。預設情況下 EnableViewState 為 true 。如果要禁止所有頁面 ViewState 功能,可以在程式配置中把 EnableViewState 設為 false 。
在控制項中:
或
DataGrid1.EnableViewState = false;
在頁中:
或
Page.EnableViewState = false;
在程式中:
在web.config中加入
在全域配置:
在machine.config中修改
EnableViewState優先順序別:
全域配置 < 程式 < 頁 < 控制項
注意:下列伺服器控制項不能禁止ViewState
Textbox
Checkbox
Checkbox List
RadioButtonList
上面控制項的狀態通過IPostBackEventHandler 和 IPostBackDataHandler介面處理,而不是ViewState的機制,所以EnableViewState沒有效果。
ViewState對象
在頁面回傳間通訊,ASP中一般利用表單的屬性和 session 來存放資料,在 ASP.NET 中也可以使用 ViewState 對象來做同樣的處理。
在ViewState存放資料:
ViewState[key] = value;
或
ViewState.Add(key, value);
取出資料:
TempStr = ViewState[key];
key不存在時返回空。
不能通過ViewState對象來訪問控制項的值。
動態建立控制項的ViewState:
當需要動態地建立一個伺服器控制項,如下建立了一個 RadioButton 控制項並加入到表單控制項集合中:
RadioButton rb = new RadioButton();
Page.Controls[1].Controls.Add(pc);
上面的代碼增加一個控制項到控制項集合末,同樣也可以插入到已有控制項中的任何位置。
RadioButton rb = new RadioButton();
Page.Controls[1].Controls.AddAt(1,pc);
通常,這些動態產生的控制項的狀態也需要產生到 ViewState 中去,但這個功能並沒有完全實現,特別是產生的控制項插入到已有的控制項中時。
當動態產生控制項和已有控制項並存時 ViewState 的結果是不可預料的。在頁面回傳時,首先非動態產生的控制項在ASPX頁中被產生,並在 Page_Init
和 Page_Load 事件中讀取 ViewState。當頁面的控制項讀取 ViewState 的值時,那些動態產生的控制項卻還沒有被產生,所以當動態產生的控制項被
產生時,頁面就會省略掉ViewState或者以剩下或許錯誤的 ViewState 來填充控制項。
所以,當需要插一個動態產生的控制項到已有控制項中去時,最好把這個控制項的 ViewState 通過EnableViewState禁止掉。
提醒:
1. 當存在頁面回傳時,不需要維持控制項的值就要把 ViewState 禁止。
2. ViewState的索引是大小寫敏感的。
3. ViewState不是跨頁面的。
4. 為了能包存在 ViewState 中,對象必須是可流化或者定義了 TypeConverter。
5. 控制項 TextBox 的 TextMode 屬性設定為 Password時,它的狀態將不會被儲存在 ViewState 中,這應該是出於安全性的考慮。
6. 在頁面 沒有回傳 或 重新導向 或 在回傳中轉到(transfer)其他頁面 時不要使用 ViewState。
7. 在動態建立控制項時要小心它的 ViewState。
8. 當禁止一個程式的 ViewState 時,這個程式的所有頁面的 ViewState 也被禁止了。
9. 只有當頁面回傳自身時 ViewState 才是持續的。