1. ViewState není odpovědný za zachování vlastních hodnot controlů mezi postbacky
ViewState není potřeba pro zachování hodnot (Value) TextBoxů, CheckBoxů, DropDownListů a jiných Web controlů mezi postbacky. Tyto hodnoty jsou uloženy standardně 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í metodySaveViewState() (v události SaveViewState) ano.
5. Jak tedy stránka/control s ViewState funguje?
Vezměme si krátký příklad:
private void btnSubmit_Click(object sender, EventArgs e) { lblMessage.Text = "Goodbye, Everyone!"; }
Co se stane při první návštěvě stránky:
- „Instantiation stage“: Nastaví se lblMessage.Text=“Hello, World!“
- „Load ViewState stage“: nic se nestane, není postback
- „Save ViewState stage“: nic se nestane, nejsou změny ViewState
- „Render Stage“: Label je renderován s „Hello, World!“
Co se stane při kliku na Change Message tlačítko:
- „Instantiation stage“: Nastaví se lblMessage.Text=“Hello, World!“
- „Load ViewState stage“: nic se nestane, ViewState stránky je prázdný
- „Raise Postback Event“: btnSubmit_Click nastaví
- lbl.Message=“Goodbye, Everyone!“
- „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!“
Co se stane při kliku na Empty postback tlačítko:
- „Instantiation stage“: Nastaví se lblMessage.Text=“Hello, World!“
- „Load ViewState stage“: nastaví se lblMessage.Text=“Goodbyw, Everyone!“ z ViewState
- „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.
- Do ViewState se ukládají všechny změny v properties controlů provedené po ukončení události Init.
- 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ů).
- U editovatelných DataGridů je vypnutí ViewState docela dřina.
- ViewState se ukládá rekurzivně včetně ViewState child-controlů a to v serializované podobě pomocí LOSFormateru.
- ViewState lze ukládat i na serveru na disk nebo do databáze pomocí překrytí metod SavePageStateToPersistenceMedium() aLoadViewStateFromPersistenceMedium(), 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.
- Další možností na zmenšení ViewState je jeho komprese a dekomprese.
- 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.
- ViewState lze i šifrovat, rozhodně se však nedoporučuje pro ukládání citlivých informací.