Co by měl každý vědět o ViewState


1) ViewState není odpovědný za zachování vlastních hodnot controlů mezi postbacky
ViewState není odpovědný za zachování hodnot (Value) TextBoxů, CheckBoxů, DropDownListů a jiných Web controlů mezi postbacky. Tyto hodnoty jsou uloženy normálně ve formulářových postback datech (POST/GET) a ASP.NET je nastaví v metodě LoadPostData() pro všechny prvky, které implementují rozhraní IPostBackDataHandler. Na to, aby nám mezi roundtripy zůstal text v TextBoxu tedy nepotřebujeme ViewState!!!
2) Na co tedy ViewState?

ViewState je vlastnost každého controlu zděděná od System.Web.UI.Control (má ji tedy i Page) a jeho základní funkčnost je založena ná následující implementaci vlastností:


public string NavigateUrl
{
get
   {
string text = (string) ViewState["NavigateUrl"];
if (text != null)
return text;
else
return string.Empty;
   }
set
   {
      ViewState["NavigateUrl"] = value;
   }
}
Hodnoty vlastností (property) se tedy ukládají do a čtou z ViewState, veškeré jejich změny se promítají do ViewState.


3) ViewState je typu StateBag
ViewState je typu System.Web.UI.StateBag, která implementuje mj. IDictionary (slouží k ukládání párů klíč-hodnota) a interně používá HybridDictionary.
Důležitou metodou StateBagu je SaveViewState(), která odpovídá za uložení ViewState.
Celý fígl je v tom, že metoda SaveViewState() uloží jenom ty vlastnosti, které se změnily po zavolání metody TrackViewState().
4) Co se tedy ukládá při uložení ViewState?
Funkčnost ViewState je úzce spojena s life-cyclem stránky a okamžikem volání metody TrackViewState(). Ta je volána na konci události Init každého controlu, a tedy i stránky (pro zjištění, zda-li již byla volána, lze použít property IsTrackingViewState.
Změny properties provedené před koncem události Init každého controlu se tedy s ViewState neukládají, veškeré další změny až do volání metody SaveViewState() (v události SaveViewState) ano.
5) Jak tedy stránka/control s ViewState funguje?
Vezměme si krátký příklad:
<script runat="server">
private void btnSubmit_Click(object sender, EventArgs e)
   {
      lblMessage.Text = "Goodbye, Everyone!";
   }
</script>
<asp:Label runat="server" ID="lblMessage" Font-Name="Verdana" Text="Hello, World!"></asp:Label><br />
<asp:Button runat="server" Text="Change Message" ID="btnSubmit"></asp:Button><br />
<asp:Button runat="server" Text="Empty Postback"></asp:Button>

Co se stane při první návštěvě stránky:



  1. "Instantiation stage": Nastaví se lblMessage.Text="Hello, World!"

  2. "Load ViewState stage": nic se nestane, není postback

  3. "Save ViewState stage": nic se nestane, nejsou změny ViewState

  4. "Render Stage": Label je renderován s "Hello, World!"

Co se stane při kliku na Change Message tlačítko:



  1. "Instantiation stage": Nastaví se lblMessage.Text="Hello, World!"

  2. "Load ViewState stage": nic se nestane, ViewState stránky je prázdný

  3. "Raise Postback Event": btnSubmit_Click nastaví

  4. lbl.Message="Goodbye, Everyone!"

  5. "Save ViewState stage": property Text od Labelu je uložena do ViewState, protože se změnila (po volání TrackViewState())

  6. "Render Stage": Label je renderován s "Goodbye, everyone!"

Co se stane při kliku na Empty postback tlačítko:



  1. "Instantiation stage": Nastaví se lblMessage.Text="Hello, World!"

  2. "Load ViewState stage": nastaví se lblMessage.Text="Goodbyw, Everyone!" z ViewState

  3. "Save ViewState stage": property Text od Labelu je uložena do ViewState, protože se změnila (po volání TrackViewState())
    "Render Stage": Label je renderován s "Goodbye, everyone!"

Shrnutí & spol.


  1. Do ViewState se ukládají všechny změny v properties controlů provedené po ukončení události Init.

  2. Protože ViewState ukládá pouze vlastnosti controlů a ne controly samotné, musíme dynamicky přidávané controly přidávat při každém postbacku stránky znovu a znovu - nejlépe během události Init (uděláme-li to však i později, metoda .Add() zajistí nahrání ViewState do přidávaných controlů).

  3. U editovatelných DataGridů je vypnutí ViewState docela dřina.

  4. ViewState se ukládá rekurzivně včetně ViewState child-controlů a to v serializované podobě pomocí LOSFormateru.

  5. ViewState lze ukládat i na serveru na disk nebo do databáze pomocí překrytí metod SavePageStateToPersistenceMedium() a LoadViewStateFromPersistenceMedium(), které standardně právě používají hidden-field ___VIEWSTATE. V některém z dalších článků si ukážeme ukládání do Session.

  6. Další možností na zmenšení ViewState je jeho komprese a dekomprese.

  7. ViewState je chráněn před změnami pomocí machine authentication check (MAC), který však pouze kontroluje, je-li ViewState od stejné verze stránky.

  8. ViewState lze i šifrovat, rozhodně se však nedoporučuje pro ukládání citlivých informací

Viz též článek ViewState vs. fáze Init, aneb jak jsem se chytil.


Robert Haken, ASP.NET MVP


Microsoft MVP




 


 


 


 


 


Comments (2)

  1. LLook says:

    Asi nejlepší text o viewstate, který jsem kdy četl, je zde: http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx

    To by měl každý vědět o ViewState.

Skip to main content