Tento článek si klade za cíl seznámit vás s implementací a použitím technologie ViewState v ASP.NET aplikacích. ViewState dovoluje uchovávat stav serverových objektů a stránky mezi jednotlivými požadavky na její zobrazení a obejít tak omezení bezestavového http protokolu.

Představení ViewState

Funkce zpracování stránky ve webových aplikacích je založena na přijetí klientova požadavku na zaslání stránky, její vygenerování serverem a odeslání klientovi. Proces generování stránky může mít různé formy – od pouhého přečtení souboru s uloženou statickou HTML stránkou až po vykonání serverových skriptů, které sestaví požadovanou stránku. Ve webové aplikaci je často potřebné udržovat stavové informace mezi jednotlivými požadavky na generování stránek s různým rozsahem platnosti – některé informace jsou platné pro všechny požadavky na aplikaci, některé pouze pro konkrétního uživatele pracujícího s aplikací a podobně.

ViewState je nástroj umožňující uchování stavu stránky a serverových objektů na ní umístěných mezi jejím opakovaným zpracováním. Narozdíl od jiných metod uchování stavu v ASP.NET aplikacích, které je možno použít v rozsahu platnosti uživatele aplikace (Session) nebo celé aplikace (Application, Cache…) je tedy jeho platnost omezena pouze po dobu tohoto opakovaného zpracování jedné stránky.

ViewState je využívána zejména pro uchování hodnot vlastností ovládacích prvků umístěných na stránce, ale lze ji samozřejmě také použít v kódu stránky. Toto lze například využít ve stránce s detailem entity načtené z databáze pro uložení hodnot, které identifikují entitu a přitom se nezobrazují ve formuláři (primární klíč a podobně). ViewState se z principu nehodí a nedoporučuje pro ukládání jakýchkoli citlivých dat. Pokud aplikace takováto data do ViewState ukládá, je nutné zvýšit jejich zabezpečení buďto nastavením šifrování ViewState nebo ukládáním ViewState do jiných úložišť než je ve výchozí implementaci předvolené skryté pole v generované stránce.

Implementace ViewState

Objekt ViewState je instancí třídy StateBag, která umožňuje ukládání dvojic název-hodnota. V rámci zpracování serverové stránky existují fáze nazývané „Load ViewState“ a „Save ViewState“ (viz též Životní cyklus ASP.NET stránky). Fáze Load ViewState je vykonána po inicializaci stránky ještě před zpracováním dat od klienta. Fáze Save ViewState je naopak vykonána před odesláním zpracované stránky na klienta. Jak lze z názvů těchto fází lehce uhodnout, fáze Load slouží k načtení uložených hodnot z ViewState a jejich předání stránce a prvkům, fáze Save naopak slouží k uložení hodnot proměnných a vlastností prvků do ViewState.

V bázové třídě serverových prvků ASP.NET (System.Web.UI.Control) existují chráněné metody LoadViewState a SaveViewState. Tyto metody jsou u každého prvku automaticky volány při zpracování stránky a umožňují prvku uložit, respektive načíst, hodnoty svých proměnných a uchovat je tak mezi opakovaným zpracováním stránky. U každého prvku je také možné zakázat práci s ViewState. Tato možnost je určena pomocí vlastnosti EnableViewState a ve výchozím stavu je nastavena na TRUE. Nastavením této hodnoty na FALSE se prvku (a všem jemu podřízeným prvkům) znemožní uchování hodnot ve ViewState.

Výchozí implementace ukládání

Za ukládání ViewState jsou v ASP.NET „zodpovědné“ metody SavePageStateToPersistenceMedium a LoadPageStateFromPersistenceMedium třídy System.Web.UI.Page. Výchozí implementace těchto metod ukládá ViewState jako hodnotu skrytého pole v generované HTML stránce a při dalším zpracování této stránky na serveru ViewState z tohoto skrytého pole obnovuje. Protože je celý ViewState vložen do jednoho řetězce, je nutné provádět při ukládání jeho serializaci a při načítání naopak jeho deserializaci. Díky tomu je také možné uložit do ViewState pouze serializovatelné objekty.

Tato výchozí implementace má několik výhod. Lze mezi ně zařadit například snadnost implementace bez zvláštních požadavků na klientské prohlížeče nebo nezatěžování serverových zdrojů (zejména paměti). Na druhé straně má však i nevýhody. K webovými vývojáři nejčastěji zmiňovaným patří narůstání velikosti zdrojového textu generovaných stránek, čímž se prodlužuje doba přenosu stránek mezi serverem a klientským prohlížečem. V praxi je možné narazit na HTML stránky o velikosti několika desítek kB, ke kterým je „přibalen“ ViewState o velikosti stovek kB. Je celkem zřejmé, že domácí uživatel, připojený k internetu pomocí komutované linky o rychlosti 34 kbit, nad takovými stránkami velmi rychle ztrácí nejen trpělivost, ale i úspory za poplatky telefonnímu operátorovi.

Druhým, již méně často zmiňovaným, ale z hlediska provozovatele aplikace podstatně nepříjemnějším problémem, je zabezpečení takto uložených hodnot. Ve výchozím nastavení stránek je totiž serializovaný řetězec pouze zakódován pomocí Base64 kódování. Formát Base64 je primárně používán ve zprávách elektronické pošty, principielně se jedná o zakódování binárních dat do tisknutelných znaků. Data uložená v tomto formátu jsou však po provedení zpětného dekódování čitelná komukoliv, kdo zakódovaný řetězec získá. Pokud je tedy takto zakódovaný ViewState odeslán na klienta, je možné jej dekódovat nejen v klientově prohlížeči, ale, pokud není pro přenos použit šifrovaný HTTPS protokol, také na kterémkoli síťovém prvku, přes který stránka putuje od serveru ke klientovi. Z tohoto důvodu je ukládání jakýchkoli citlivých dat do ViewState značným bezpečnostním rizikem.

Zvýšení zabezpečení šifrováním

ASP.NET umožňuje nastavit šifrování ViewState pomocí 3DES algoritmu, nicméně výchozí nastavení toto neprovádí a tato možnost se málokdy využívá – ať již proto, že o ní vývojáři nevědí, nebo díky určitému snížení výkonu aplikace při šifrování a dešifrování ViewState. Šifrování ViewState je nutné v konfiguraci povolit na dvou místech. Jednak v konfiguračním souboru aplikace (soubor web.config, případně lze toto nastavení provést pro všechny aplikace na serveru uvedením parametru do souboru machine.config) a druhak direktivou na konkrétní stránce. Povolení šifrování se provádí uvedením následujícího konfiguračního parametru v souboru web.config:

<machineKey validationKey=“AutoGenerate“ decryptionKey=“AutoGenerate“ validation=“3DES“ />

Pro použití ve stránce se zapnutí provádí pomocí změny hodnoty EnableViewStateMAC na TRUE:

<%@ Page language=“c#“ … EnableViewStateMAC=“True“ %>

Ukázka použití v aplikaci

Po vykonání metody LoadViewState je možné v kódu prvku, typicky ve vlastnostech prvku, načítat hodnoty uložené ve ViewState. Příklad na uložení řetězcové vlastnosti prvku s názvem „Text“:

public string Text {
  get {
    return (string) ViewState[„Text“];
  }
  set {
    ViewState[„Text“] = value;
  }
}

Zmíněné metody LoadViewState a SaveViewState je možné překrýt a naprogramovat si vlastní logiku uložení proměnných prvku do ViewState. Ve většině prvků, které nevyžadují speciální vlastnosti, to však není nutné a je možné použít výchozí implementaci.

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