Přesměrování stránky s odesláním dat metodou POST
21. července 2009 13:05
webové stránky
Včera jsem do jednoho projektu řešil problém s přesměrováváním
v ASP.NET na jinou stránku a zároveň jí poslat data metodou POST. Na
to již samotné Response.Redirect(url) bohužel nestačí, a tak
jsem začal pročítat dokumentaci, různé diskuse a internetové stránky a
nakonec jsem si napsal celkem elegantní řešení.
Základem celého řešení je vytvoření vlastní třídy pojmenované
RemotePost, která bude umět na požadovanou Url odeslat
fiktivně vytvořenou XHTML stránku obsahující formulář a skryté hodnoty,
které se předají metodou POST. Tedy mluvím o metodě
POST, ale řešení je uděláno univerzálně tak, aby bylo možné zvolit
jakou metodou se má formulář odeslat, stejně tak i zvolit některé
další vhodné věci.
Třída RemotePost
Vytvářená třída tedy
vypadá následovně:
Proměnné
Pro uchovávání kolekce skrytých hodnot fomuláře, které budou na
požadované Url odeslány, je použita specializovaná kolekce
NameValueCollection (namespace
System.Collections.Specialized), která umožňuje jako
jednotlivé prvky kolekce uchovávat dvojici textů a to
název (Key) a hodnotu (Value), tedy
ideální pro uchovávání hodnot <imput type="hidden" name="{nazev}"
value="{hodnota}" />.
Vlastnosti
- FormName
- obsahuje název fiktivně vytvářeného formuláře
- defaultní hodnota je form1
- Method
- určuje metodu odeslání formuláře (POST/GET)
- defaultní hodnota je POST
- Target
- určuje frame nebo window, do kterého se volaná stránka zobrazí, což
lze využít například, pokud se potřebujete vrátit z iframe do
rodičovského rámu (stránky)
- hodnota může být libovolný textový název začínající písmenem od
A do Z a nebo speciální hodnota z variant: _blank,
_parent, _search, _self, _top
- Url
- hodnota obsahuje Url adresu stránky, na kterou bude formulář
s hodnotami odeslán (a která se tedy po přesměrování zobrazí)
Konstruktor
Třída obsahuje jediný konstruktor, který inicializuje novou instanci
třídy RemotePost a nastaví defaultní hodnoty jednotlivých vlastností.
Metody
- Add(string name, string value)
- metoda umožňuje přidávat jednotlivé hodnoty (do kolekce ukryté
v proměnné values), které budou předány ve formuláři
- každá hodnota se tedy skládá z názvu (name) a hodnoty
(value); z nich pak ve formuláři bude vygenerován
<input
type="hidden" name={name} value={value} />
- Submit()
- tato metoda zajistí samotné vytvoření fiktivníh formuláře se
skrytými hodnotami a jeho odeslání na požadovanou Url
- v principu se vytvoří nová XHTML stránka, která obsahuje
formulář se skrytými hodnotami z kolekce obsažené v instanci
naší třídy RemotePost a pomocí JavaScriptu je zajištěno, že ihned při
načtení stránky dojde k odeslání našeho formuláře (
<body
onload="document.{FormName}.submit()">)
- tato metoda je nosnou částí celé třídy RemotePost a obsahuje hlavní
výkonnou část
Zdrojový kód třídy RemotePost
A nyní se tedy můžeme podívat na samotný zdrojový kód
třídy:
public class RemotePost
{
private NameValueCollection values = new NameValueCollection();
public string Url { get; set; }
public string Method { get; set;}
public string FormName { get; set; }
public string Target { get; set;}
public RemotePost()
{
this.Url = string.Empty;
this.Method = "post";
this.FormName = "form1";
this.Target = string.Empty;
}
public void Add(string name, string value)
{
values.Add(name, value);
}
public void Submit()
{
HttpResponse res = HttpContext.Current.Response;
res.Clear();
res.Write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
res.Write("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
res.Write("<head></head>");
res.Write(string.Format("<body onload=\"document.{0}.submit()\">", FormName));
res.Write(string.Format("<form name=\"{0}\" method=\"{1}\" action=\"{2}\" target=\"{3}\" >", FormName, Method, Url, Target));
for (int i = 0; i < values.Keys.Count; i++)
{
res.Write(string.Format("<input name=\"{0}\" type=\"hidden\" value=\"{1}\" />", values.Keys[i], values[values.Keys[i]]));
}
res.Write("</form>");
res.Write("</body></html>");
res.End();
}
}
Použití třídy RemotePost
A jak tedy můžeme naši třídu RemotePost využít? Velmi jednoduše,
stačí vytvořit novou instanci, určit Url, přidat potřebné hodnoty a
zavolat metodu Submit(). Tedy například takto:
RemotePost post = new RemotePost();
post.Url = "http://ukazky.jerrysohn.net/remote-post/read-data.aspx";
post.Add("firstname","Jan");
post.Add("lastname","Novak");
post.Submit();
Tímto způsobem můžete posílat data při obsluze nejrůznějších
událostí v ASP.NET stránce a můžete tak posílat bez problémů data
na libovlná URL nejen pomocí parametrů v Url, ale hlavně metodou POST
přímo v těle stránky.
Příklad ke stažení
Aby bylo vše ještě jednodušší a jasnější, na svém ukázkovém
serveru (http://ukazky.jerrysohn.net/remote-post/)
jsem připravil jednoduchý příklad. Ten si navíc můžete také stáhnout
v přiloženém souboru pod tímto článkem.
Snad se vám tento postup bude někdy hodit a třeba vám ušetří spoustu
času při hledání nějakého vhodného návodu.
autor: jerrysohn |