ASP .NET MVC – routing

Adresy internetowe są naszą codziennością, nieustannie przekazujemy sobie URL’e, odwiedzamy kolejne strony – jak to wszystko wygląda od bebechów? Tematyką tego wpisu będą podstawy Routingu w ASP .NET MVC.

Wygląd adresów URL – z pozoru błaha rzecz – jest istotnym elementem witryn internetowych. Ma to związek między innymi z SEO (Search Engine Optimization). Gdy adresy są: dobrze skonstruowane, nie zawierają długich ciągów znaków numerycznych, łatwo je zapamiętać – są lepiej indeksowane przez wyszukiwarki internetowe. Użytkownicy również szybciej utrwalą je sobie w pamięci i na tym nam zależy.

Tworzenie szablonów adresów

W aplikacji ASP .NET MVC w folderze App_Start odnajdź klasę RouteConfig.cs to miejsce w którym możemy zdefiniować szablony adresów URL. Statyczna metoda tej klasy RegisterRoutes wywoływana jest w Global.asax.cs

Domyślnie zdefiniowana trasa wygląda następująco:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace WebApplication1
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

Prezentuje ona konwencję trójczłonową: {controller}/{action}/{id} gdzie jest to odpowiednio: nazwa kontrolera, nazwa akcji i parametr Id opcjonalnie do niej przekazywany.

W celu poprawienia SEO naszej witryny, a także ułatwienia czytelności adresów URL dla użytkowników możemy rozbudować metodą o kilka dodatkowych tras. Należy zwrócić uwagę na kolejność definiowana jako, że rozpatrywane są po kolei.

Na potrzeby tego przykładu załóżmy, że chcemy zdefiniować routing dla sklepu internetowego z grami planszowymi. Przykładowe adresy które chcemy uzyskać to:

http://localhost:50713/gry-1.html
http://localhost:50713/strony/Kontakt.html
http://localhost:50713/kategorie/horror

Jak to zrobić?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace BoardGameShopMVC
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "ProductDetails",
                url: "gry-{id}.html",
                defaults: new { controller = "Store", action = "Details" }
            );

            routes.MapRoute(
                name: "StaticPages",
                url: "strony/{viewname}.html",
                defaults: new { controller = "Home", action = "StaticContent" }

            );

            routes.MapRoute(
                name: "ProductList",
                url: "kategorie/{categoryName}",
                defaults: new {controller = "Store", action = "List"},
                constraints: new { categoryName = @"[\w]+"}
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

Jak wygląda budowanie trasy w praktyce?

1. Nazwij routing
2. Określ wzorzec według którego ma być budowany adres URL
3. Odnieś się do odpowiedniego kontrolera oraz akcji.

Przykład 1: „ProductDetails”

Trasa służąca na przekierowanie na stronę detalu (konkretnego produktu) np. http://localhost:50713/gry-1.html

  • name – nazwa, możemy ją nadać i wykorzystać w helperze HTML action. Gdy np. chcielibyśmy wygenerować link do strony i upewnić się, że będzie użyty właśnie ten szablon adresu URL.
  • url – nasz szablon adresu np. http://localhost:50713/gry-1.html co oznacza, że zmienna id=1; trafi jako parametr akcji Details kontrolera StoreController
  • Defaults – określamy nazwę odpowiedniej klasy kontrolera i akcji która ma zostać wywołana dla tego routingu.

Przykład 2: „StaticPages”

Trasa do obsługi stron statycznych np. http://localhost:50713/strony/Kontakt.html

  • Controller – HomeController
  • Action – StaticContnet (która przyjmuje parametr viewname i zwraca widok o dokładnie tej nazwie)

Przykład 3: „ProductList”

Trasa pozwalająca przejść do konkretnej kategorii gier planszowych np. http://localhost:50713/kategorie/horror

  • Controller – StoreController
  • Action – List która przyjmuje parametr categoryName
  • Constraints – parametr genrename ma spełniać dodatkowe wymagania, a konkretnie spełnić wyrażenie regularne (Regex) – ma zawierać tylko znaki alfanumeryczne. Czyli gdyby ktoś zdefiniował ścieżkę kategorie/!!!12312test – to ten routing by tego nie wykrył, bo parametr categoryName nie spełnia REGEXa

Abyś mógł przetestować jak działa powyższy routing dodaj odpowiadające im kontrolery (do folderu Controllers), stwórz w nich akcje przyjmujące założone w trasowaniu parametry. Pozostaje jedynie utworzenie testowych widoków i będziesz mógł sprawdzić jak to się je.

  • Mała wskazówka: aby domyślnie adresy URL kończące się na .html skierować na pipeline ASP .Net a nie zwracać statycznego pliku rozbuduj konfigurację pliku Web.config o następujące linie kodu:
<system.webServer>
	<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

Spowoduje to, że wszystkie żądania HTTP będą kierowane przez ASP .Net, a nie jak mogłoby się czasem zdarzyć jedynie przez IIS.

Pozdrawiam Wojtek