ASP.NET MVC Routing

Trong công nghệ làm web với mô hình MVC, dù là bất kỳ framework nào như Ruby on Rails, laravel, hay ASP.NET MVC thì Routing luôn là một phần quan trọng và cần ưu tiên khi bạn muốn làm quen với framwork đó. Hôm nay, mình xin giới thiệu về Routing trong ASP.NET MVC.

1. Giới Thiệu

ASP.NET Routing cho phép bạn sử dụng các URL không dẫn đến một file cụ thể in Website. Bởi vì URL không dẫn đến một file cụ thể trong ứng dụng web, bạn có thể làm cho URL trở nên thân thiện hơn với người dùng. Ở ASP.NET application không sử dụng routing (ASP.NET webform - đã bị khai tử), một request từ một URL thường được dẫn đến một tập tin xử lý request đó. Chẳng hạn:

http://server/application/Products.aspx?id=4

sẽ dẫn đến file có tên Product.aspx có chứa code xử lý và render để trả lời trình duyệt. Web page này sử dụng query string id = 4 để xác định nội dung được hiển thị. (Quen thuộc quá phải không các bạn, ngày xưa bạn nào làm webform chắc không lạ gì.)

Với MVC, ở ví dụ sau:

    http://server/application/Products/show/beverages

URL sẽ không truy vấn tới file Products/show/beverages mà sẽ được định nghĩa bởi routing, chẳng hạn nếu Routing định nghĩa URL là server/application/{area}/{action}/{category} thì ở request URL trên, are = Product, action = show và category = beverages.

2. Router

Browser (trình duyệt) yêu cầu một địa chỉ từ Controller Acction trong ASP.NET MVC Framework được gọi là định tuyến URL (URL routing). URL routing sẽ chỉ định yêu cầu (request) tới Controller Action. URL routing sử dụng một bảng định tuyến để điều khiển các yêu cầu (request). Bảng định tuyến được tạo khi ứng dụng được chạy lần đầu tiên. Bảng định tuyến được thiết lập trong file Global.asax.

3. URL Patterns

Một URL pattern có thể chứa các parameters. các parameters ngăn cách nhau bởi dấu /(slash character).

Khi một request URL được yêu cầu, URL được phân tách thành cách đoạn như trong Routing đã định nghĩa, các giá trị được truyền vào từ URL sẽ được xử lý dưới dạng key - value.

Trong URL pattern ta xác định chúng bằng cách để vào dấu {}, và định nghĩa dấu phân cách cho chúng, VD /, -. Ví dụ {language}-{country}/{action} là một URL pattern đúng còn {language}{country}/{action} là một URL pattern sai vì không có dấu phân cách.

Bảng dưới đây cho ta một vài ví dụ về URL pattern đúng và request URL tương ứng.

Định nghĩa Router Ví dụ về URL đúng
{controller}/{action}/{id} /Products/show/beverages
{table}/Details.aspx /Products/Details.aspx
blog/{action}/{entry} /blog/show/123
{reporttype}/{year}/{month}/{day} /sales/2008/1/5
{locale}/{action} /US/show
{language}-{country}/{action} /en-US/show

Với ASP.NET MVC, URL điển hình sẽ chứa {controller}{action}.

4. Thêm Routing vào MVC application

Thông thường, nếu bạn không cần các URL tương đối đặc biệt, bạn có thể sử dụng Routing được định nghĩa sẵn khi tạo project MVC, nếu bạn muốn chỉnh sửa routes trong ứng dụng MVC, bạn có thể sử dụng MapRoute. Ví dụ dưới đây là đoạn code định nghĩa routes trong ứng dụng MVC.

public class MvcApplication : System.Web.HttpApplication
{
    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 = "" }  // Parameter defaults
        );

    }

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }
}

5. Setting Default Values cho URL parameters

Khi bạn định nghĩa một route, bạn có thể xác định default value cho paramete của route. Default value sẽ được sử dụng khi trong URL không chứa parameter. Ví dụ dưới đây cho chúng ta thấy cách thêm default values, sử dụng MapPageRoute

  void Application_Start(object sender, EventArgs e)
{
    RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Category/{action}/{categoryName}",
        "~/categoriespage.aspx",
        true,
        new RouteValueDictionary
            {{"categoryName", "food"}, {"action", "show"}});
}

Khi ASP.NET xử lý URL request, route sẽ được định nghĩa như bảng dưới đây:

URL Parameter values
/Category action = "show" (default value) categoryName = "food" (default value)
Category/add action = "add" categoryName = "food" (default value
/Category/add/beverages action = "add" categoryName= "beverages"

6. Làm thế nào URL khớp với Rotues

Khi Routing xử lý các URL request, nó sẽ cố gắng xử lý URL đề phù hợp với một route nào đó, với các điều kiện sau đây:

  • Các routes patterns bạn định nghĩa hoặc các default route patterns, nếu có trong project.
  • Thứ tự bạn thêm chúng vào Routes collection.
  • Bất kỳ default value nào bạn định nghĩa cho một route.
  • Bất kỳ hạn chế(validate) nào bạn định nghĩa cho một route.
  • Bạn xác định một route để request tới một file vật lý.

Để tránh việc sai sót trong xử lý các request, bạn phải xem xét tất cả các điều kiện trên khi bạn định nghĩa routes. Bạn cũng nên tránh việc trùng lặp routes không cần thiết như ví dụ sau: Ví dụ: bạn có các rotues như sau:

  • Route 1 được định nghĩa là: {controller}/{action}/{id}
  • Route 2 được định nghĩa là: products/show/{id} Route sẽ không bao giờ phải xử lý bất kỳ một request nào từ URL vì routes 1 được định nghĩa trước, và các request phù hợp với route 2 sẽ luôn phù hợp với route 1, như: request http://server/application/products/show/bikes phù hợp với route 2 nhưng nó sẽ được xử lý bới route 1 với các giá trị:
  • controller là product
  • action là show
  • id là bikes Default values sẽ được sử dụng nếu request không chứa parameter được định nghĩa. Bạn có thể xem xét ví dụ sau:
  • Route 1: {report}/{year}/{month}, với default values là year và month.
  • Route 2: {report}/{year}, với default value flà year. Route 2 sẽ không bao giờ được xử lý request, bởi vì với default là year, month thì request phù hợp với Route 2 sẽ luôn phù hợp với Rotue 1. Điều này có thể trái với mong muốn của bạn vì Route 1 là report theo tháng còn route 2 là report theo năm. Bạn có thể tránh được điều này bằng cách thêm vào một constaint, như là: annual/{report}/{year}monthly/{report}/{year}/{month}.

7. Kết Luận

Trên đây chỉ là một số vấn đề cơ bản trong route của ASP.NET MVC, ở phần sau, mình sẽ giới thiệu cách custom route, RESTFUL routes, nested route và một số vấn đề advanced hơn. Cám ơn Bạn đã xem hết bài viết!

Tham khảo:


All Rights Reserved