\


 Friday, 07 May 2004
Uložení důležitého stavu serverových ovládacích prvků v ASP.NET 2.0

ASP.NET 1.0 přineslo pro vývojáře WWW aplikací několik zásadních novinek. Jednou z nejlepších je simulace stavového chovaní prvků pomocí ViewState. U každého serverového ovládací prvku je před vyrenderováním stránky volána metoda SaveViewState, ve které prvek uloží všechny informace potřebné k obnovení stavu. Kompletní stavová informace stránky je poté uložena ve skrytém (hidden) poli na klientovi. Po odeslání formuláře (PostBacku) je volána metoda LoadViewState všech prvků a je jí předán stav uložený metodou SaveViewState. Metoda LoadViewState obnoví stav prvku a poskytne tak vývojáři i uživateli skoro dokonalou iluzi stavového chování známého hlavně z těžkých klientů. Slovo "skoro" jsem použil záměrně, protože je často nutné z výkonnostních důvodů ukládání ViewState zakázat, aby na klienta a pak zpět na server nebyly přenášeny velké objemy dat. Můžeme sice přepsat metody LoadViewStateFromPersistenceMedium a SaveViewStateToPersistenceMedium třídy Page a ukládat ViewState například do databáze na serveru, ale v praxi se tento postup příliš neujal. Ukládání ViewState můžeme zakázat všem ovládacím prvkům na stránce, častěji ale ukládání ViewState zakážeme pouze u vybraných prvků, jež by do ViewState přidaly nejobjemnější položky. Po zakázání ViewState se ale většinou setkáme s problémy, jejichž řešení zabere nezanedbatelné množství času. Například DropDownList si po zákazu ViewState "nepamatuje" vybranou položku (SelectedIndex), takže uložení a nastavení indexu vybrané položky musíme při každém odeslání formuláře řešit sami. ViewState v .Net Frameworku 1.0 vyznává zásadu "všechno nebo nic", ale my bychom často potřebovali ukládat důležitý stav bez ohledu na nastavení ViewState vývojářem. Nemusíme ukládat do ViewState zrovna celý číselník, ale index vybrané položky přenosovou linku nijak nezatíží a programování extrémně zjednoduší.
ASP.NET 2.0 proto přichází s novinkou - kromě ViewState lze ukládat i takzvaný ControlState. O ukládání do ControlState rozhoduje výhradně vývojář serverového ovládacího prvku, jehož odpovědností je, aby do ControlState byla uložena jen data důležitá pro základní činnost prvku. Určitě ale do ControlState nesmí být ukládány DataSety, kolekce ani jiné objemné objekty. Dále platí, že stavová data jsou uložena do ControlState nebo do ViewState, nikdy ne do obou stavových úložišť! Výsledný ControlState celé stránky je ukládán na klientovi ve skrytém poli s nepřekvapivým názvem __CONTROLSTATE.
Ukládání do ControlState se příliš neliší od ukládání do ViewState. Hlavním rozdílem je to, že serverový ovládací prvek si musí vynutit ukládání a načítání ControlState voláním metody RegisterRequiresControlState třídy Page.

protected override void OnInit(EventArgs e)
{
   base.OnInit(e);
  Page.RegisterRequiresControlState(this);
}


Ve veřejné metodě SaveControlState před vyrenderováním stránky uložíme důležitý stav prvku a vrátíme jej. Návratovým typem metody je typ object, takže můžeme vrátit jakýkoli serializovatelný(!) objekt. V ukázkovém kódu je ukládán ControlState bázové třídy a poté hodnota vlastnosti SelectedIndex.

public override object SaveControlState()
{
  object baseState = base.SaveControlState();
   object[] savedSate = { baseState, this.SelectedIndex};
   return savedState;
}

Metoda LoadControlState po odeslání formuláře obnoví dříve uložený ControlState. Z argumentu state je po přetypování obnoven nejdříve ControlState bázové třídy a poté hodnota vlastnosti SelectedIndex.

public override void LoadControlState(object state)
{
   object[] savedState =(object[]) state;
   base.LoadControlState(savedState[0]);
   this.SelectedIndex = (int) savedState[1] ;
}



Friday, 07 May 2004 15:47:00 (Central Europe Standard Time, UTC+01:00)       
Comments [2]  ASP.NET