Artykuł

maj 01 2011
0

Tworzenie reguł routingu w ASP.NET MVC 3

Kilka miesięcy temu, we wpisie związanym ze tworzeniem stron, jeszcze w ASP.NET MVC 2, otarłem się delikatnie o zagadnienie reguł routingu w ASP.NET MVC. Generalnie, jest to dość istotne zagadnienie, dlatego warto zapoznać się z nim trochę szerzej, Tym bardziej, że wpływa ono w sposób znaczący zarówno na przepływ danych jak i ruch użytkowników naszej witryny.

Czym jest Routing w ASP.NET MVC?

Routing jest to mechanizm, który w naszej aplikacji internetowej, odpowiada za prawidłowe wywoływanie wszystkich akcji, używanych w naszej witrynie. W regułach routingu, znajdują się definicje reguł, które pozwolą na obsłużenie wszystkich akcji dostępnych w aplikacji.

Jak działa routing? Ideą tego mechanizmu, jest rozłożenie adresu konkretnej podstrony na elementy składowe i szukanie pasującego wzorca w pliku Global.asax, który jest integralnym elementem każdej aplikacji zbudowanej w ASP.NET MVC. W pliku, tym znajduje się metoda RegisterRoutes, która pozwala na rejestrowanie kolejnych metod routingu. Domyślnie zawartość tej metody, wygląda mniej więcej tak:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = 
            UrlParameter.Optional } // Parameter defaults
    );
}

Przeanalizujmy pokrótce niniejszy kod. Na początku, definiujemy adresy, które mają być ignorowane. Kolejnym elementem metody, jest już reguła routingu, przyjrzyjmy się jej bliżej. Metoda MapRoute, w tej wersji posiada następujące parametry:

  • Nazwę - w tym przypadku Default
  • Adres URL wraz z parametrami - w tym przypadku {controller}/{action}/{id}, czyli kontroler/akcja/identyfikator
  • Obiekt przechowujący wartości domyślne - w tym przypadku {controller = "Home", action = "Index", id = UrlParameter.Optional }, czyli kolejne wartości dla URLa zdefiniowanego wyżej. Odpowiednio kontroler Home (HomeController), akcja Index oraz id pobrany z paska adresu. Taka właśnie akcja zostanie wykonana, w sytuacji gdy użytkownik poda np. tylko sam adres strony, czyli np.
    http://localhost:16180/

Adresem, który pasuje do powyższej reguły, jest np. taki adres:

http://localhost:16180/Home/Edit/1

Który oznacza tyle, że korzystamy z kontrolera HomeController, wyzwalamy dla niego akcję Edit i podajemy identyfikator użytkownika 1.

Taki adres URL, choć ma całkiem logiczną postać, nie wygląda do końca zachęcająco. Przy tak prostej aplikacji, można by uprościć wywołania poszczególnych metod, a nawet je spolszczyć. Przekonajmy się zatem jak napisać własne reguły routingu:)

Własne reguły routingu

Tworzenie własnych reguł routingu, w oparciu o wiedzę zaprezentowaną wyżej jest już bardzo łatwe. Dla przykładu, chcemy w prosty sposób wywoływać akcję edycji, np.

http://localhost:16180/Edytuj/1

Gdzie 1 to identyfikator użytkownika. Jak tego dokonać? Wystarczy, że do metody RegisterRoutes w pliku Global.asax dodamy taki oto wpis:

routes.MapRoute(
    "PersonEdit", // Route name
    "Edytuj/{id}", // URL with parameters
    new { controller = "Home", action = "Edit", id = 
        UrlParameter.Optional } // Parameter defaults
);

Co tu się właściwie dzieje? Reguła ma tylko jeden parametr, czyli identyfikator. Istotą reguły są wartości domyślne, czyli kontroler Home oraz akcja Edit. W gruncie rzeczy, ta reguła odpowiedzialna jest tylko za edycję użytkownika, czyli nie jest tak uniwersalna jak ta pierwsza (domyślna), ale jak widać na screenie, działa i jest po polsku, czyli bardziej swojsko:)

Stosowanie reguł routingu ma jeszcze inne zalety. Oprócz tego, że możemy wywoływać akcje w sposób bardziej dla nas dogodny, to aplikacja sama dba oto, by nasze linki automatycznie rozpropagowały się w aplikacji, we wszystkich miejscach gdzie wykorzystywana jest ta komenda. Aby tak się jednak stało, linki muszą być budowane za pomocą rozszerzenia ActionLink, czyli np. w ten sposób:

<%: Html.ActionLink("Edytuj", "Edit", new { id=item.PersonId }) %>

Dzięki takiej konstrukcji, ASP.NET automatycznie wygeneruje link do akcji edycji bazując na wpisach zawartych w regułach routingu. Jest to zdecydowanie lepsze rozwiązanie, niż wykorzystanie tradycyjnych znaczników a i budowanie linków ten sposób.

Ograniczenia (z ang. Constraints)

Ostatnią rzeczą, którą chciałbym dziś opisać, to ograniczenia, które możemy zastosować dla naszych reguł. Co mogą dać nam ograniczenia? Możemy np. zablokować dostęp do określonych akcji, za pomocą metody POST, czy GET. Dla przykładu, możemy stworzyć ograniczenie takie, aby lista osób mogła być wyświetlana tylko przy użyciu metody żądania GET. Jak tego dokonać? Bardzo prosto:

routes.MapRoute(
    "PersonList", // Route name
    "Osoby", // URL with parameters
    new { controller = "Home", action = "List", id = 
        UrlParameter.Optional }, // Parameter defaults
    new { httpMethod = new HttpMethodConstraint("Get") }// Constraints
);

Co wyróżnia ten kod od poprzednich? Nowy obiekt ograniczeń, który działa na podobnej zasadzie jak obiekt z wartościami domyślnymi. Kolejne ograniczenia możemy dodawać po przecinku.

Innym przykładem ograniczeń, może być zastosowanie wyrażeń regularnych dla parametru id. Akcje edycji i usuwania korzystają z tego parametru, aby uniknąć komplikacji, możemy dodać ograniczenie, które sprawdzi, czy wartość parametru id jest liczbą. Przykładowo dla akcji edycji, będzie wyglądać to tak:

routes.MapRoute(
    "PersonEdit", // Route name
    "Edytuj/{id}", // URL with parameters
    new { controller = "Home", action = "Edit", id = 
        UrlParameter.Optional }, // Parameter defaults
    new { id = @"\d+" } // Constraints
);

Oczywiście, możemy tutaj zapisać dowolne inne ograniczenie, na jakie tylko pozwolą wyrażenia regularne:)

Na koniec mała UWAGA. Jak zauważył w komentarzu Piotr ważna jest kolejność reguł - własne reguły musza znajdować się przed domyślnymi.

Data ostatniej modyfikacji: 06.06.2013, 08:43.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus