Jak vypadá životní cyklus ASP.NET stránky řízené pomocí událostí? Událostně řízené zpracování je zásadní změnou při tvorbě ASP.NET stránek oproti ASP stránkám, kde jsme museli o zpracování rozhodovat podle předaných parametrů. V jakém pořadí jsou události generovány a kdy dochází k jejich zpracování, si přiblížíme v následujícím textu.

Životní cyklus ASP.NET stránky začíná s požadavkem klienta na její zobrazení. Server nahrává každou stránku při žádosti o její zobrazení klientovi a po jejím zpracování ji opět odstraňuje ze zpracování. Od nahrání až do odstranění stránky se dle jejího vytvořeného objektového modelu zpracují všechny informace, které jsou stránce předány. Ve výsledku je pro klienta vygenerován HTML kód.

Pokud bychom takto uvažovali a vynechali ono vytvoření objektového modelu stránky, podobá se zpracování klasické ASP stránce. Přístup, kdy je zpracování započato na prvním řádku stránky a veškeré zpracování je ukončeno posledním řádkem stránky, je zde plně nahrazen a je potřeba se od tohoto přístupu zcela odpoutat. Právě onen objektový přístup nám velice usnadní a zpřehlední samotné programování.

Pojďme si tedy projít zpracování stránky od jejího požadavku až po její odeslání klientovi a odstranění ze zpracování.

Inicializace – Init

Při požadavku na stránku dochází k inicializaci stránky. Je vyvolána událost Init a je zpracována metoda OnInit(). Tuto metodu můžeme ve své stránce předefinovat override protected void OnInit(EventArgs e) a plně tak nahradit metodu OnInit() bázové třídy.

Při této události dochází k inicializaci objektů uvnitř stránky a inicializaci nastavení pro zpracování příchozího požadavku. Takto zinicializované objekty a nastavení jsou používány po celou dobu zpracování stránky. Nyní se také registrují události jednotlivých prvků stránky, které chceme zachytit.

Pokud v této metodě dynamicky vytvoříme serverový prvek, potom se nám údaje o tomto prvku uchovají mezi jednotlivými přechody stránky – údaje o prvku jsou ukládány do vlastnosti ViewState. Tato metoda je též vhodná k registrování událostí jednotlivých prvků. Například pokud chceme na formulář umístit tlačítko a tomuto tlačítku budeme chtít přiřadit určitou funkcionalitu, dejme tomu, že toto tlačítko si vyžádá aktuální serverový čas. Kód, který toto bude zajišťovat, může vypadat takto:

override protected void OnInit (EventArgs e) {
   … // zde je registrace ostatnich udalost
  this.Load += new System.EventHandler(this.Page_Load);
  Button btn = new Button(); // vytvorim tlacitko
  bnt.Text = „Serverový čas“; // nastavení textu na tlačítku
  btn.CssClass = „tlacitko“; // přiřazení kaskádoveho stylu pro tlačítko (class)
  btn.Click += new System.EventHandler(this.CasServeru); // registrace události pro tlačítko
  Control ctrl = Page.FindControl(„frmMain“); // je třeba si najít formulář
  ctrl.Controls.Add(btn); // do formuláře vložíme tlačítko
}
private void CasServeru(object sender, System.EventArgs e) {
  Response.Write(DateTime.Now.ToString()); // vypíšeme úplně jednoduše aktuální čas
}

Pokud vytvoříme tímto způsobem jakýkoli serverový prvek a registrujeme u něj událost, potom i při submitu (PostBacku) stránky dojde k vykonání této události.

Nahrání ViewState dat – LoadViewState

Při provádění metody LoadViewState() jsou nahrány stavové informace všech prvků na stránce (zároveň s informacemi o stránce, která je také prvkem). Jednotlivé prvky mohou tuto metodu opět předefinovat protected override void LoadViewState(object savedState) a ovlivnit tak ukládání informací o sobě samém.

Zpracování předaných dat – LoadPostData

V metodě LoadPostData() dochází ke zpracování vstupních formulářových dat a aktualizaci vlastností podle nich. K aktualizaci vlastností může dojít pouze u těch prvků, které podporují rozhraní IPostBackDataHandler. Jako v předchozích případech je možné metodu LoadPostData() předefinovat a ovlivnit tak aktualizaci vlastností u tohoto prvku. V této metodě se rozhoduje, zda bude vyvolána událost (oznámení) o změně příslušející k danému prvku stránky.

Load

Událost Load je vstupním místem pro zpracování všech požadavků, tato událost je zpracována v metodě OnLoad(). Všechny objekty na stránce jsou uspořádány do stromu a inicializovány, formulářové prvky odpovídají předaným datům od klienta. V tento okamžik je již možné s jednotlivými prvky manipulovat a nastavovat jim vlastnosti.

Oznámení o změně dat – RaisePostDataChanged

Oznámení o změně dat RaisePostDataChanged, která jsou zpracovávána metodou RaisePostDataChangedEvent(), je závislé na tom, zda v prvku stránky došlo ke změně oproti původnímu stavu. Tato událost se vyvolává u prvků (i u stránky), které podporují interface IPostBackDataHandler a kde metoda LoadPostData() z tohoto rozhraní vrátila hodnotu true.

Pokud máme na stránce například textové pole, potom je tato událost vyvolána v případě, že uživatel do tohoto pole vložil nový text a my jsme se chtěli nechat o této akci informovat. Znamená to, že v události OnInit jsme si zaregistrovali událost TextChanged txtZprava.TextChanged += new System.EventHandler(this.ZmenaZpravy);.

Vyvolání události – RaisePostBackEvents

Vyvolání události RaisePostBackEvents je zapříčiněno chováním klienta a vyvolává příslušné události, jež byly zaregistrovány v metodě OnInit() pro příslušný prvek. Tuto událost mohou vyvolat pouze prvky, které mají implementován interface IPostBackEventHandler.

Zde bych se mohl vrátit k ukázce prezentované u popisu události OnInit. V této ukázce byla metoda, která vypisovala aktuální čas na serveru. Tato metoda představovala obsluhu události Click. Metoda GetServerTime() se tak nevykoná ihned po jejím zaregistrování, ale až v průběhu zpracování stránky po provedení inicializace a nastavení vlastností prvků a objektů. Postup pro takovéto zpracování je uzpůsoben tomu, aby se před provedením jednotlivých událostí prvků, stihly inicializovat a nastavit všechny prvky na stránce a nebyly ovlivněny jiným zpracováním.

PreRender

V události PreRender je poslední možnost pro změnu vlastností prvků stránky nebo stránky samotné a uchování těchto hodnot ve vlastnosti ViewState. Tato událost je vyvolána pouze u těch prvků, které se budou zobrazovat na stránce. Opět zde máme možnost předefinovat metodu OnPreRender() pro změnu výchozí chování této metody.

Uložení stavu stránky – SaveViewState

Při zpracování metody SaveViewState() dojde k uložení stavu prvků na stránce. Ukládání stavu jednotlivých prvků je možné ovlivnit nastavením vlastnosti EnableViewState na hodnotu false. Zpracovaný stav všech prvků je převeden na textový řetězec a zakódován (zašifrování je provedeno pomocí kódování BASE64). Tento stav stránky je poté poslán zpět na klienta v prvku input – hidden pole – označeného __VIEWSTATE. Každý prvek může předefinovat metodu SaveViewState() a ovlivnit tak ukládání informací.

Render

Vygenerování výstupu, jenž je poslán klientovi. Metoda Render() zajišťuje kompletní vykreslení všech prvků na stránce, které se mají zobrazit klientovi. Vykreslením v tomto smyslu myslím vygenerování posloupnosti tagů pro zařízení, jež je na klientské straně. Může se jednat o HTML, ale také o WML, a to v různých verzích, záleží na verzi klientského zařízení.

Pokud předefinujeme metodu Render(), potom ovlivníme konečný výstup, jenž naše stránka (prvek) poskytne klientovi. Změny vlastností u prvků stránky, které bychom provedli v této metodě, se projeví na klientovi, avšak nebudou již promítnuty do zpětného zpracování.

Dispose

V metodě Dispose() je již stránka vykreslena a je prováděn „úklid“ všech existujících unmanaged objektů.

V prostředí .NET máme možnost používat dva typy kódů, takzvaný managed kód a unmanaged kód. Pod pojmem managed kód je třeba si představit takový kód, který spravuje a stará se o něj CLR (Common Language Runtime), zjednodušeně řečeno jakýsi virtuální stroj zpracovávající operace. Unmanaged kód je potom takový kód, který nevyužívá výhody a služby nabízené CLR. Takový kód nepotřebuje ke svému běhu prostředí .NET Framework. V případě, že budete psát svoje aplikace pouze za pomoci jazyků jako jsou C# nebo Visual Basic .NET, potom budete vždy generovat managed kód. Pokud použijete jazyk C++, máte naprostou volnost a můžete se rozhodnout, zda použít managed kód nebo unmanaged kód.

Odstranění stránky – UnLoad

Událost UnLoad je vyvolána pro zpracování všech ukončovacích operací spojených s odstraněním prvků a stránky ze zpracování. Tato událost je vyvolávána u stránky, avšak některé prvky, které jsou na stránce, nemusí tuto událost vyvolávat a veškerý „úklid“ zajistí již v metodě Dispose(). Po provedení události UnLoad je stránka odstraněna ze zpracování a klient obdrží výstup stránky.

Jak tvoříme všechny prvky

Vedle shora uvedených událostí je třeba se zmínit o metodě CreateChildControls(), která provádí zpracování prvků uvnitř stránky a prvků uvnitř prvků (kontejnerů). Metoda zajišťuje uspořádání všech prvků na stránce do hierarchického stromu. Jelikož k volání této metody dochází několikrát během zpracování stránky, není možné ji přesně zařadit do posloupnosti zpracování. Poprvé je volána při nahrávání stránky (Load), následně během navazování prvků na data (DataBinding), nebo při vykreslování (Render).

Ukázka

V této ukázce si můžete prohlédnout jednoduchou stránku. Abych vám lépe přiblížil, jak dochází ke zpracování jednotlivých událostí, je na této stránce nastaven diagnostický výstup Trace. Tento výstup se zobrazuje pod samotnou stránkou a můžeme zde nalézt několik velice důležitých informací. V první tabulce se dozvíme informace o požadavku na naši stránku. Druhá tabulka nás zajímá nejvíce, neboť zobrazuje informace o vyvolaných událostech, dobách zpracování jednotlivých událostí od počátku zpracování stránky i o době zpracování jednotlivých metod. V následující tabulce je potom zobrazen strom (vnoření) jednotlivých prvků na stránce. Jak si můžete všimnout, je zde zobrazen i prvek btnDynamic, který byl přidán dynamicky při zpracování stránky. Další tabulky jsou také zajímavé, ale nebudu je více rozebírat.

Blížíme se k poslednímu řádku

V tomto článku jsme si tedy ukázali všechny události a metody, kterými prochází každá stránka od přijetí požadavku až po její výsledné zobrazení. Téměř všechny metody určené pro zpracování je možné předefinovat a upravit si tak jejich funkcionalitu dle vlastních požadavků a pro konkrétní řešený problém.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět