morzel.net

.net, js, html, arduino, java... no rants or clickbaits.

View State dla TextBox i innych kontrolek implementujących IPostBackDataHandler

Czytając oficjalny trening kit do egzaminu 70-515 natrafiłem na taki tekst: "With view state, data is stored within controls on a page. For example, if a user types an address into a TextBox and view state is enabled, the address will remain in the TextBox between requests.". Skoro takie zdania padają w zalecanym podręczniku, nic dziwnego, że łatwo pogubić się w tym jak ASP.NET Web Forms próbuje radzić sobie z naturalną dla HTTP bezstanowością... ;)

Kontrolka TextBox ze strony ASPX:

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

Jest na stronie HTML renderowana jako tag input:

<input name="TextBox1" type="text" id="TextBox1" />

Skoro tak, to dla zachowania wartości kontrolki między requestami nie ma konieczności przechowywania wartości pola TextBox1 w ukrytym polu __VIEWSTATE. By się o tym przekonać stwórz prostą stronę zawierajacą kontrolki TextBox i Button:

...

<body>
    <form id="form1" runat="server">
    	<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    	<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" /
    </form>
</body>
</html>

i dodaj handler dla zdarzenia Click przycisku, którego jedynym zadaniem jest rozwijanie tekstu znajdującego się w kontolce TextBox1:

protected void Button1_Click(object sender, EventArgs e)
{
    TextBox1.Text += "X";
}

Następnie uruchom stronę i aktywuj narzędzie pozwalające na monitorowania komunikacji pomiędzy przeglądarką a serwerem. Interesuje nas badanie danych formularza przesyłanych na serwer przy postbacku... Jeśli używasz IE polecam program Fiddler, pod Firefoxem skorzystaj z dodatku Firebug. Możesz też użyć wbudowanego w ASP.NET mechanizmu Trace - w tym celu dopisz Trace="true" do dyrektywy @Page. Ja przeprowadzę test przy użyciu narzędzi deweloperskich dostarczonych wraz z przeglądarką Chrome (zakładka "Network").

Na poniższym screenie widać jakie dane formularza (request HTTP POST) zostały wysłane przy pierwszym naciśnięciu przycisku:

Dane formularza przy pierwszym postbacku

Tutaj widać dane z drugiego postbacka:

Dane formularza przy drugim postbacku

Jeśli porównasz dane z pierwszego i drugiego żądania, zobaczysz, że zmiana wartości TextBox1.Text nie wpływa na wartość pola __VIEWSTATE. Rozszerzanie tego pola byłoby marnotrastwem zasobów łącza skoro tekst jest wysyłany na serwer w osobnym polu o nazwie TextBox1.

Klasa System.Web.UI.WebControls.TextBox jest jedną z kilku klas implementującyh interfejs IPostBackDataHandler. Interfejs ten wymaga istnienia metody LoadPostData. Po zakończeniu incjalizacji strony (ale przed zdarzeniem Load), wykonywane jest ładowanie danych z View State (LoadViewState) a następnie (o ile kontrolka implementuje IPostBackDataHandler) z danych formulrza (LoadPostData). Właściwość Text kontolki typu TextBox może być zatem ustawiona nawet jeśli mechanizm View State jest wyłączony (poprzez ustawienie EnableViewState="false").

Czy nie można więc zupełnie zrezygnować z mechanizmu View State dla TextBoxa i podobnych kontrolek?

Nie. View State przydaje się np. wtedy gdy obsługiwane jest zdarzenie TextChanged (dla porównania wartości aktualnej i poprzedniej). Może mieć też zastosowanie gdy ustawiana jest inna właściwość kontrolki niż ta utożsamiana z wartością pola (np. ForeColor).