MVC Routing - Úvod
Routování v MVC umožňuje zpracování URL friendly requestů a jejich následné delegování správným metodám správných controllerů včetně předání příslušných parametrů. Všechny routy jsou ukládány v RouteCollection a nastavení se provádí typicky v AppStart/RouteConfig.cs. Přístup k routovací tabulce je však možný z mnoha míst aplikace.
Přidání nového routovacího pravidla je možné pomocí metody MapRoute:
public static void RegisterRoutes(RouteCollection routes) { routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { id = @"\d+" } ); }
V příkladu výše je vidět výchozí nastavení routování. Příkladem budiž URL:
http://www.website.com/articles/detail/85
Request bude zpracován controllerem ArticlesController, metodou Detail a předá se jí parametr id = 85.
V úvahu připadá i URL ve tvaru:
http://www.website.com/articles
Request bude zpracován opět controllerem ArticlesController ale protože není v url specifikována action, použije se výchozí: Index. Parametr id se nepředá žádný, protože je definován v routovacím pravidle jako Optional.
Chybou nám ale selže následující request URL:
http://www.website.com/articles/detail/muj-clanek
Request by v tomto případě mohl zpracovat ArticlesController a metoda Detail ale parametr id je vyžadován jako číslo (viz. constraints), což v tomto případě není splněno.
Vlastní routes
Velmi často se hodí napsat si vlastní pravidla. Zde rovnou uvádím příklady z praxe:
Priklad1 ukazuje situaci, kdy všechny url, které mají tvar blog/{id} zpracuje stejný controller Blog a metoda Detail, které se předá stringový identifikátor. Identifikátor je v tomto případě povinný, protože není přímo řečeno, že by byl UrlParameter.Optional. Identifikátor musí být číselného charakteru.
routes.MapRoute( name: "Priklad1", url: "blog/{id}", defaults: new { controller = "Blog", action = "Detail" }, constraints: new { id = @"^[0-9]+$" } );
Priklad2 se zase hodí, pokud chci, aby jeden controller na základě id zpracovávala odlišná metoda (neboli action). Výchozí akcí je Index. Podmínkou pro action je, že se musí jednat o text bez speciálních znaků a číslic.
routes.MapRoute( name: "Priklad2", url: "blog/{action}", defaults: new { controller = "Blog", action = "Index" }, constraints: new { action = @"^[a-z]+$" } );
Priklad3 ještě ukazuje, jak použít více parametrů:
routes.MapRoute( name: "Priklad3", url: "blog/{action}/{id}/{page}", defaults: new { controller = "Blog", action = "Detail", page = UrlParameter.Optional }, constraints: new { id = @"^[a-z]+$" } );
V tomto případě jsou přípustné například URL:
http://www.website.com/blog/archiv/osobni/9 http://www.website.com/blog/archiv/programovani http://www.website.com/blog/detail/mujclanek
Univerzální routovací pravidla mají však určité nevýhody:
- hůře se udržují
- snadno vznikají chyby voláním neexistujících controllerů a actions
- nutnost důsledného ošetření všech action metod
- obvykle horší "vzhled" url
Z mé vlastní zkušenosti doporučuji vytvářet více routovacích pravidel a snažit se o maximálně krátké, čisté a účelné URL. Toho lze docílit například použitím constraints.
Attribute Routing
Od verze MVC 5 je k dispozici Attribute Routing, který umožňuje výrazně snazší popis routování pomocí Data Annotations, např.:
[Route("{id:int}")] public ActionResult Detail(int id) { ... }
Tomuto tématu se pověnuji v jiném článku.