--普遍荒謬的認為 ViewState 對象保持著控制項例如 TextBox 的值。
大多數 ASP.NET 的開發人員認為 ASP.NET 的 ViewState 對象負責保持類似 TextBox 文本控制項的值,因而這些值甚至在回傳後還被保留著。但是這卻不是這麼回事。
我將用一個例子來解釋。你可以下載專案檔(http://www.codeproject.com/aspnet/ViewState/ViewState.zip),建立一個名為 ViewState 的虛擬目錄,並運行這個應用程式。讓我們從一個 C# 語言的 Web 項目開始。
建立一個新的 ASP.NET Web 應用程式,然後在 WebForm 上放置以下控制項:
放一個伺服器 TextBox 控制項,一個 HTML 伺服器文本控制項(帶 runat=server 屬性的普通 HTML 輸入框),一個普通的 HTML 輸入控制項,和一個伺服器端 Label 控制項。4 個控制項命名如下:
txtWebServerTest
txtHtmlServerTest
txtHtmlTest
lblTest
設定上邊3個文字框的 Text 或 Value 屬性為“Initial Text”。設定下邊Label控制項的 Text 屬性為“Initial Label Value”。
設定第一個和最後一個控制項的 EnableViewState 屬性為 false。
在所有控制項的下邊,放置 2 個按鈕控制項(Button),分別設定它們的 Text 屬性為“Change Label’s Text”和“Postback to Server”。在第一個按鈕的點擊事件裡寫入以下代碼:
private void btnChangeLabel_Click(object sender, System.EventArgs e)
{
lblTest.Text = "Label's Text Changed";
}
在第二個按鈕的點擊事件裡不寫任何代碼。它僅僅提交頁面到伺服器。
現在運行這個應用。你可以看到控制項上你預先設定的初始化文本。
現在,改變所有文字框的文本,把他們設定為字串“Changed Text”。再點擊提交到伺服器的按鈕。可以看到前邊的 2 個文字框保持了它們的值,儘管它們的 ViewState 屬性被設定為 false。但是下一個文字框(簡單的 HTML 輸入控制項),當頁面被重新載入時,丟失了修改了的值。
大多數開發人員可能期望所有的 3 個文字框都丟失它們更改了的值(“Changed Text”),並且在頁面重新後,他們期望字串“Initial Value”被重新寫回到文字框中,因為我們已經把 ViewState 屬性設定為 disabled 了。
這種行為的原因是,ViewState 是不負責儲存諸如 TextBoxes, dropdowns, CheckBoxList 等這些繼承自 IPostBackDataHandler 介面的控制項的更改了的值的。在 Page_Init() 事件後,有個稱為 LoadViewState 的事件,在這裡 Page 類從隱藏的域 __VIEWSTATE 中為諸如 ViewState 屬性為 enabled 的 Label 控制項裝載值。然後 LoadPostBackData 事件被出發,在這裡 Page 類從 HTTP 提交頭(POST headers)中裝載繼承自 IPostBackDataHandler 介面的控制項的值。
現在,再次運行這個應用,這次點擊“Change Label’s Text” 按鈕。當頁重新裝載時,你將看到用程式改變(按鈕的點擊事件代碼所為)的值丟失了,也就是說,我們沒有看到 Label 的文本變成“Label's Text Changed”。而是再次看到 Label 的初始值。這是因為 Label 控制項不是繼承自 IPostBackDataHandler 介面,於是 ViewState 負責穿越回傳期保持它的值。但又因為 ViewState 是 disabled 的, 所以 Label 丟失了點擊“Change Label’s Text” 按鈕時它被改變的文本。
現在使能 Label 控制項的 ViewState 狀態,在點擊相同的按鈕後,你會看到改變了的值(“Label's Text Changed”)。
所以我們斷定,繼承自 IPostBackDataHandler 介面的控制項將保持它們的值,即使它們的 ViewState 狀態被關閉,因為它們的值被儲存在 HTTP 提交頭裡。
作者 Vivek Thakur 簡介:MVP (ASP.NET),印度德裡市。
[原文]
Myth Regarding ViewState in ASP.NET
By Vivek Thakur
Common myth that ViewState holds values for controls such as TextBoxes.
Introduction
Most ASP.NET developers think that the ASP.NET ViewState is responsible for holding the values of controls such as TextBoxes so that they are retained even after postback. But this is not the case.
I'll explain this with an example. You can download the project files from the link above (you can set the Virtual Directory by the name of ViewState) and run the application. Let's start with a web project in C#.
Open a new ASP.NET Web Application, and on the WebForm, place the following controls accordingly:
Place a web server TextBox control, an HTML server text box control (normal HTML input box with runat=server), a normal HTML input control, and a web server Label control. Name the four controls as:
txtWebServerTest
txtHtmlServerTest
txtHtmlTest
lblTest
Set the Text/Value property to “Initial Text” for the above three TextBoxes, and set the Text property of the Label control to “Initial Label Value”.
Set the EnableViewState property to false for the first and the last controls.
Beneath these controls, place two Button controls and set their text as “Change Label’s Text” and “Postback to Server”. On the button click event handler of the first button, write the following code:
private void btnChangeLabel_Click(object sender, System.EventArgs e)
{
lblTest.Text = "Label's Text Changed";
}
There is no code on the second button’s Click event. It just submits the page to the server.
Now run this application. You can see the initial texts in the controls as you have set.
Now, change the text in all TextBoxes and set them to “Changed Text”. Now click the Post to Server button. What happens is that the first two textboxes retain their values, in spite of the ViewState property being set to false. But the last textbox, which is a simple HTML input control, loses the modified value when the page is reloaded.
Most developers would have expected all three textbox controls to lose their modified values (“Changed Text”), and after page re-loading, they expect “Initial Value” being written on all textboxes as we had disabled the ViewState.
The reason for this behavior is that ViewState is not responsible for storing the modified values for controls such as TextBoxes, dropdowns, CheckBoxList etc., i.e., those controls which inherit from the IPostBackDataHandler interface. After Page_Init(), there is an event known as LoadViewState, in which the Page class loads values from the hidden __VIEWSTATE from the field for those controls (e.g., Label) whose ViewState is enabled. Then the LoadPostBackData event fires, in which the Page class loads the values of those controls which inherit from the IPostBackDataHandler interface, (e.g., TextBox) from the HTTP POST headers.
Now, start the application again, and this time, click the “Change Label’s Text” button. When the page reloads, you will see that the programmatic change (made by our code in the event handler of the button’s Click event) was lost, i.e., we don’t see the Label’s text changed to “Label's Text Changed”. Instead, we see the initial value of the Label again. This is because the Label control does not inherit from the IPostBackDataHandler interface. So the ViewState is responsible for persisting its value across postbacks, and since it has been disabled, the Label loses its value after clicking the “Change Label’s Text” button.
Now enable the ViewState for the Label control, and you can see the modified value (“Label's Text Changed”) after clicking the same button.
So we conclude that controls which inherit from the IPostBackDataHandler interface will retain their values even if the ViewState has been disabled, as their values are stored in HTTP POST headers.
About Vivek Thakur
Vivek Thakur is MVP (ASP.NET) and currently working in a self funded firm as Technology Head in Delhi, INDIA. Vivek graduated with B.Tech from Indian Institute of Technology (IIT), Delhi. Though his expertise lies in Microsoft .NET platform, he is comfortable in J2EE platform besides C/C++, Prolog and MPI-CH. He has deep interest in programming, Chaos Theory and artificial intelligence. Besides his love for software architecture and design, Vivek also focuses on project management skills and has good experience of managing small to medium sized projects. He is also involved in giving training sessions and tutoring.
He is a strong advocate of Chaos Theory in software systems and management.
Vivek also loves music and is the lead guitar player in his band: TechTonica. He loves song writing and music composition, besides listening to different genres of music.
To know more about him one can visit his personal website at: http://www.vivekthakur.com/.