ASP.NET ve verzi 2.0 přináší řadu vylepšení a umožňuje programátorům snáze tvořit sofistikovanější aplikace. Jedním z těch velmi zajímavých, nicméně dle mého názoru málo diskutovaných vylepšení, je i Cross-page Postback. Jedná se o techniku, která umožňuje postback, jak jej znáte z ASP.NET 1.x, odeslat na jinou stránku.

Co je Cross-page Postback

V ASP.NET 1.x je naprosto běžným scénářem takzvaný Postback. V některých situacích je velmi výhodné, že stránka se „vrátí“ v aktualizované podobě. Například v případě DataGridu (respektive jeho nástupce, prvku GridView), kdy uživatel smaže záznam – stránka zjistí, že uživatel chce odstranit záznam z tabulky, zjistí si identifikátor záznamu, vymaže řádek z databáze, znovu načte řádky, které se mají zobrazit (nyní už bez smazaného záznamu), a vše se vypíše opět na stejnou stránku. Dalšími scénáři, kdy je Postback na stejnou stránku více než nutností, je například stránkování v mřížkách, hlasování v anketách a podobně.

Někdy je však dobré předat Postback jiné stránce. Může jít například o situaci, kdy máte formulář, který má za úkol vytvořit uživatele. Jako první budete chtít od uživatele základní údaje o jeho osobě – jméno, příjmení, adresu – a na druhé stránce si uživatel vybere, které kategorie vašeho webu ho zajímají. Tento problém se dá vyřešit pomocí takzvaných wizardů nebo můžete využít Cross-page Postback.

Vyzkoušejte si ukázku (zdrojový kód).

Jak vyvolat Cross-page Postback

Vyvolat Cross-page Postback není o mnoho složitější než vyvolat klasický Postback. Stačí přidat k prvku, který by měl vyvolat klasický Postback, odkaz na stránku, kam se má Postback odeslat:

<form id=“form1″ runat=“server“>
 Napiš svoje jméno:
 <asp:TextBox ID=“tbName“ runat=“server“></asp:TextBox>&nbsp;
 <asp:Button ID=“Button1″ runat=“server“ Text=“Odeslat“ PostBackUrl=“Submit.aspx“ />
</form>

Toto tlačítko nyní ví, že má Postback odeslat na stránku Submit.aspx. Dalším logickým krokem je získání hodnot z prvků formuláře. Obecně se můžete uchýlit k několika způsobům, přičemž asi nejpoužívanější si zde ukážeme.

Jak získat odkaz na předchozí stránku

Nejjednodušší pro implementaci bude nejspíš nějakým způsobem vyhledat prvek na stránce, která Postback vyvolala, a s ním pak dále pracovat. Není to sice tak úplně v duchu objektově orientovaného programování, ale v některých případech se tento postup může hodit. Podívejme se tedy, jak na to:

protected void Page_Load(object sender, EventArgs e)
{
 if (PreviousPage != null && PreviousPage.IsCrossPagePostBack)
 {
  TextBox tbName = (TextBox)PreviousPage.FindControl(„tbName“);
  Label1.Text = tbName.Text;
 }
}

První krok, který bychom měli provést, je test. První test by měl ověřit jestli vůbec existuje nějaká předchozí stránka (objekt typu System.Web.UI.Page přístupný přes vlastnost PreviousPage), přesněji, není-li odkaz na takovou stránku null. Pokud tedy nějaký odkaz existuje, otestujeme, jestli tato stránka vyvolala Postback. Máme-li jistotu, že takové akce proběhly, můžeme začít pracovat s vyvolaným postbackem.

Na prvním formuláři máme textové pole, jehož obsah hodláme vypsat do labelu na druhé stránce. Vytvoříme tedy nový objekt typu TextBox s názvem tbName. Pomocí metody FindControl(string id) třídy Page získáme odkaz na prvek na předchozí stránce. Ten přetypujeme na typ TextBox a přiřadíme našemu objektu tbName. Tímto na nové stránce získáme plný přístup k všem členům textového pole z první stránky, tedy i k vlastnosti Text, která je pro nás klíčová. Nyní je už jen dílem okamžiku vypsat text na stránku.

Tento postup má své nesporné výhody, v demonstrovaném příkladě je však zcela evidentní, že není potřeba plný přístup k TextBoxu – stačí nám přeci pouze jeho vlastnost Text. Můžeme tedy využít trošku jiné techniky, která je plně v duchu objektově orientovaného programování.

Objektově orientovaný postup

Stručně řečeno jde o způsob, kdy vystavíme na původní stránce vlastnosti a druhé stránce sdělím, jakého typu má očekávat typ PreviousPage. Přes tento odkaz poté budeme přistupovat k vystaveným vlastnostem.

Chcete-li k předchozí stránce přistupovat takto „přísně typově“, vede k tomu o něco více kódu, nicméně budete-li mít složitější formulář, bude váš kód mnohem přehlednější.

Nejprve musíte sdělit, jakého typu předchozí stránka je. K tomu slouží direktiva <%@ PreviousPageType %>. Této direktivě můžete buď předat přímo název typu předchozí stránky (atribut TypeName) nebo virtuální cestu k dané stránce (atribut VirtualPath). Je-li v našem příkladě předchozí stránka Default.aspx, může direktiva PreviousPageType vypadat například takto:

<%@ PreviousPageType VirtualPath=“~/Default.aspx“ %>

Dalším krokem by mělo být vystavení některých specifických vlastností, které náš typ nezdědil od System.Web.UI.Page. Pro nás je momentálně důležitý pouze text v textovém poli, tedy vlastnost Text objektu tbName. Ke kódu v souboru Default.aspx.cs proto přidáme následující konstrukci:

public string Name
{
 get { return tbName.Text; }
}

Naši třídu jsme tím obohatili o novou vlastnost, která vrací přesně ten typ informací, které potřebujeme. Máme-li na stránce, kam Postback směřuje, direktivu určující typ předchozí stránky, můžeme v kódu postupovat mnohem intuitivnějším způsobem:

protected void Page_Load(object sender, EventArgs e)
{
 if (PreviousPage != null && PreviousPage.IsCrossPagePostBack)
 {
  Label1.Text = PreviousPage.Name;
 }
}

V modelovém příkladu jsme se k výsledku dobrali složitější cestou, budete-li však mít na stránce více prvků, jejichž hodnoty budete chtít použít na stránce nové, je zcela zřejmé, že tento přísně typový přístup má své nesporné výhody. Kdybych měl první postup, tedy pomocí metody Page.FindControl(), vpustit do reálného provozu, nejspíš bych pro jistotu napsal takovýto kód:

TextBox tbName = null;
object o = PreviousPage.FindControl(„tbName“);
if (o != null) tbName = (TextBox)o;

Nikdy totiž s jistotou nemůžete předpokládat, že se na nějaké v tu chvíli „neznámé“ stránce nachází ten nebo onen objekt. Když za půl roku změníte formulář, něco přidáte, něco odeberete, případně přejmenujete, tento kód se směle přeloží bez jakéhokoli varování. Problém nastane až za běhu – až když se bude aplikace snažit najít dotyčný objekt. Až v tu chvíli vyhodí chybové hlášení.

Budete-li však postupovat přísně typově, nemůže se vám takové nedopatření stát. Pokud byste po čase změnili objekty na stránce nebo přejmenovali vlastnosti, překladač chybu odhalí už během překladu.

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