Attribute Routing 在原作者 Tim McCall 捐獻給 .NET Framework 後,在 ASP.NET MVC 5 與 ASP.NET Web API 2 的專案裡就可以使用,如果是使用 ASP.NET MVC 5 專案的話,可以在 SystemWeb.Mvc 命名空間裡看到,
這一篇將會對於 Attribute Routing 的使用做個簡單的說明。
AttributeRouting
https://github.com/mccalltd/AttributeRouting
https://github.com/mccalltd/AttributeRouting/wiki
如果是其他版本的 ASP.NET MVC 專案,例如 4.0 , 3.0 的版本也是可以使用,但是要另外從 NuGet 裡將 Attribute Routing 給加入到專案,
事前準備
Attribute Routing 的設定方式並不是很複雜,請先將 AttributeRouting 官網的說明以及 AttributeRouting 在 GitHub 上的 Wiki 先看過一遍,就可以知道基本的使用方法,只需要在 Controller 或是 Action 方法上標注 Route 的 Attribute 然後加入 Route 路徑所使用的名稱就可以了,但是有一個動作記得要先做,就是在 ~/App_Start/RouteConfig.cs 裡要加入「routes.MapAttributeRoutes()」
ASP.NET MVC 5 專案
ASP.NET MVC 4 專案
在已經公開的 ASP.NET MVC 5.1 RC1 裡,從官方所公開的 Sample 專案裡,並沒有在 ~/App_Start/RouteConfig.cs 裡加入「route.MapAttbibuteRoute()」,
並不是說不用加入 route.MapAttbibuteRoute() 的使用,而是可以在另外的地方使用不一樣的方式,在 Global.asax 裡要加入 Attribute Routes 的註冊使用,其實作法都是一樣的。
操作示範
以下的操作示範將會以 ASP.NET MVC 5 所整合的 AttrobuteRouting 為主,使用上會與 Tim McCall 的版本會略有不同,所以要特別注意。
在 Controller 類別上標注 RoutePrefix 然後指定路徑名稱「Home」,就表示進入這個 Controller 要使用「Home」,
如果想要改用別的路徑名稱進入 HomeController 的話,可以在 RoutePrefix 裡使用其他的名稱。
註:使用整合進 .NET Framework 的 AttributeRouting,Controller 只能使用一個 RoutePrrfix。
設定 Controller 預設的 Action
可以在 Controller 上使用 Route attribute,然後指定進入這個 Controller 預設的 Action,
Action 使用 Route attribute
在 Action 方法上可以標注多個 Route attribute,這邊建議可以在 Route attribute 上面加上各個 Route 設定所預設使用的路徑註釋,這樣會更加清楚各個 Route 設定的對應,
Route Constraints
當一個 Action 方法有需要輸入參數的時候,如果想要限定輸入參數的條件時,就可以在 Route attribute 裡加入 Route Constraints 來加以限制,例如我另外建立了一個 ProductController,然後加入一個 ListByCategory 的 Action 方法,方法的參數是要輸入使用 CategoryName 字串,一定要輸入參數值,但是最小長度為 2 最大長度為 15,所以設定的方式如下:
有關 Route Constraints 的使用,可以參考 AttributeRouting 的官網或是 Wiki 說明,
或是也可以參考「Attribute Routing in ASP.NET MVC 5 - .NET Web Development and Tools Blog」的說明,
使用多個 Route attribute
一個 Action 方法可以使用多個 Route attribute,以下的例子是依據輸入的國家與郵遞區號顯示客戶資料,
localhost:15227/Customer/Brazil
localhost:15227/Customer/Brazil/05487-020
日期限制
這邊用一個簡單的例子來做說明,假如我們想要用指定日期來列出訂單資料的話,可以用以下的設定,
但如果我們想要列出某一年份或是某一年某月的訂單資料呢?這邊就不能用上面的設定方式,但是另外建立一個 Action 方法然後再做 Route 設定,如下:
我們可以使用 Route Constraints 來設定傳入參數的限制,年月日都必須是數字,年份可以設定最小與最大值,不過我這邊是沒有做設定,月份設定最小為 1 最大為 12,日設定最小為 1 最大為 31。
其實這個 ListByDateRange 方法的功能與剛才的 ListByDate 有所重疊,兩個可以並存,但是輸入完整日期就不會進入 ListByDateRange 方法,因為 ListByDate 的 Route 設定會比 ListByDateRange 更早被 Mapping 到,所以剛才的 ListByDate 方法就可以不用了,查詢指定訂單日期的功能就可以用 ListByDateRange 方法,以下是 ListByDateRange 方法的完整內容:
// Get: /Order/1997
// Get: /Order/1997-7
// Get: /Order/1997/7
// Get: /Order/1999-7-29
// Get: /Order/1999/7/29
[Route("{year:int}")]
[Route("{year:int}-{month:int:min(1):max(12)}")]
[Route("{year:int}/{month:int:min(1):max(12)}")]
[Route("{year:int}-{month:int:min(1):max(12)}-{day:int:min(1):max(31)}")]
[Route("{year:int}/{month:int:min(1):max(12)}/{day:int:min(1):max(31)}")]
public ActionResult ListByDateRange(int year, int? month, int? day)
{
List<Order> orders = new List<Order>();
var query = db.Orders
.Include(o => o.Customer)
.Include(o => o.Employee)
.Include(o => o.Shipper);
if (!month.HasValue && !day.HasValue)
{
var startDate = new DateTime(year, 1, 1);
var endDate = new DateTime(year, 12, 31);
query = query.Where(x => x.OrderDate.HasValue
&& x.OrderDate.Value >= startDate
&& x.OrderDate.Value <= endDate);
orders = query.ToList();
}
else if (!day.HasValue)
{
var startDate = new DateTime(year, month.Value, 1);
var endDate = month.Value.Equals(12)
? new DateTime(year + 1, 1, 1).AddDays(-1)
: new DateTime(year, month.Value + 1, 1).AddDays(-1);
query = query.Where(x => x.OrderDate.HasValue
&& x.OrderDate.Value >= startDate
&& x.OrderDate.Value <= endDate);
orders = query.ToList();
}
else
{
string date = string.Format("{0}/{1}/{2}", year, month, day);
DateTime orderDate;
if (DateTime.TryParse(date, out orderDate))
{
query = query.Where(x => x.OrderDate.HasValue
&& x.OrderDate.Value == orderDate);
orders = query.ToList();
}
}
return View("List", orders.OrderBy(x => x.OrderDate).ToList());
}
只輸入年份
輸入年份與月份
輸入指定日期
這一篇就先講到這裡,其實 Attribute Routing 的設定還有很多種方式,詳細的使用說明還是先查看 Attribute Routing 官網以及在 GitHub 上的 Wiki,然後再多做練習,如此對 Attribute Routing 的使用就可以得心應手。
使用 Attribute Routing 並不是說就可以拋棄原本在 RouteConfig.cs 的 Route 設定,Attribute Routing 是可以讓我們用夠為彈性的方式來設定 Route。
參考連結:
https://github.com/mccalltd/AttributeRouting
https://github.com/mccalltd/AttributeRouting/wiki
Attribute Routing in ASP.NET MVC 5 - .NET Web Development and Tools Blog
以上
Kevin 大:
回覆刪除在文章前段『就是在 ~/App_Start/RouteConfig.cs 裡要加入「routes.MapAttributeRoutes()」』的 routes.MapAttributeRoutes(),是不是 routes.MapMvcAttributeRoutes() ? :)
Kevin 大:
回覆刪除看來我搞錯了 :P
應該說.... 我在那邊的說明是會容易讓人誤解.... 簡言之,我寫得不好 Orz
刪除原來有這麼好用的東西~
回覆刪除