URL Rewriting v ASP.NET
10. dubna 2007
|
Radek Kropík
|
U mnoha webových stránek se můžete setkat se zvláštním formátem URL adresy, a to tzv. "Cool URL“. Výjimkou není ani tento magazín, kdy například adresa nějakého článku může být třeba ve tvaru "/Clanky/80=zajimavy-clanek.aspx" namísto obvykle používaného formátu "/Clanek.aspx?idClanku=80“. Už na první pohled je jasné, že prvně uvedený formát adresy je pro čtenáře magazínu snadněji zapamatovatelný a co víc, takovýto formát adres mají raději i vyhledávače, kteří ji snáze zaindexují a přiřadí ji občas i dokonce větší váhu. Jak takové zajímavé adresy dosáhnout si povíme dále.
Metoda RewritePath
V tomto případě vstupuje do hry soubor global.asax a serverová metoda Application_BeginRequest. V těle této metody jde přistupovat k objektu HttpContext a volat zde metodu RewritePath, která provede samotné přemapování adresy. Funkce pro přemapování může vypadat například takto:
void Application_BeginRequest(Object sender, EventArgs e)
{
string sUrl = HttpContext.Current.Request.Url.PathAndQuery;
string sId;
Match shoda;
Regex rRegex = new Regex("/Clanky/(\\d+).aspx");
shoda = rRegex.Match(sUrl, 0);
if (shoda.Groups[1].Success)
{
sId = shoda.Groups[1].Value;
HttpContext.Current.RewritePath
("../VypisClanek.aspx?idClanku=" + sId);
return;
}
}
Tímto přemapováním můžeme používat například adresu ve tvaru server.cz/Clanky/XX.aspx, kde XX nahradíme ID článku. Zde je třeba říci, že adresář Clanky, který v příkladu uvádím, nemusí fyzicky vůbec existovat. Po zavolání metody RewritePath skutečně dojde k přepisu adresy a zpracuje se stránka VypisClanek.aspx přesně tak, jak jsme si přáli. Vše funguje přesně podle našeho přání, ale až do momentu, kdy na stránce VypisClanek.aspx provedeme PostBack – třeba když máme na stránce anketu, kometáře apod. V takovém případě bude PostBack proveden na adresu VypisClanek.aspx?idClanku=xxx, a máme adresu zase ve starém formátu, a to přece nechceme. Jedna z možností jak toto obejít, je zavolat metodu RewitePath ještě jednou a to v metodě Page_Load stránky VypisClanek.aspx, a to například takto:
protected void Page_Load(object sender, EventArgs e)
{
int idClanku;
string sId = Request.Params["idClanku"];
Context.RewritePath(Request.RawUrl, "", "", true);
if (Int32.TryParse(sId, out idClanku))
{
//Zde načteme článek z databáze podle id článku
}
}
Jen ještě doplním, že je potřeba relativní odkazy ve stránce, kde používáme přemapování, tj. všechny href u odkazů, src u obrázků apod. adresovat relativně vzhledem k novému formátu adresy, popřípadě je adresovat absolutně k URL webu.
HttpHandlerFactory v akci
Druhou, a podle mě lepší možností pro přepis URL adresy je použití třídy implementující rozhraní IHttpHandlerFactory, která bude zpracovávat jí předané URL. Parametry se v tomto případě předávají pomocí kolekce Context.Items, dostupnou během celého procesu zpracování stránky. Příklad takovéto třídy může vypadat takto:
public class RemapUrl : IHttpHandlerFactory
{
public IHttpHandler GetHandler(HttpContext Context,
string requestType, string url, string pathTranslated)
{
string Path =
Context.Request.AppRelativeCurrentExecutionFilePath.
ToLower();
string Page;
if (Path.StartsWith("~/clanky/"))
{
Page = "~/VypisClanek.aspx";
}
Context.Items["idClanku"] =
System.IO.Path.GetFileNameWithoutExtension(pathTranslated);
return PageParser.GetCompiledPageInstance(Page,
Context.Server.MapPath(Page), Context);
}
public void ReleaseHandler(IHttpHandler handler)
{
}
}
Dále je třeba v souboru web.config v sekci system.web nastavit filtr, aby výše vytvořený Handler věděl, jaké požadavky má zpracovat.
<httpHandlers>
<add verb="*" path="Clanky/*.aspx" type="RemapUrl" />
</httpHandlers>
A to je vlatně vše, co je zde potřeba k přepisování adresy udělat. K parametru idClanku lze pak přistupovat ve stránce VypisClanek.aspx pomocí Context.Items["idClanku“]. Samozřejmě i zde platí to, co jsme si výše řekli o adresování vložených odkazů a dalších objektů, jako jsou obrázky apod.
protected void Page_Load (object sender, EventArgs e)
{
int.Parse(Context.Items["idClanku"].ToString())
//Zde načteme článek z databáze podle id článku
}
Je teď jen na vás, kterou možnost si k přepisování URL vyberete. Samozřejmě je možné dále URL upravovat, například k ID článku přidat název článku, jako to vidíte v tomto magazínu. Ale to už je opravdu na vás, co dále s URL provedete, aby vypadala ještě lépe.