以下為常規MVC路由
1
2
3
4
5
|
config.Routes.MapHttpRoute( name: "DefaultApi" , routeTemplate: "api/{controller}/{id}" , defaults: new { id = RouteParameter.Optional }, ); |
如果我們要實現類似以下效果路由的話,使用常規公約路由比較麻煩。
1
2
|
order/Miles/三只松鼠干果/2袋 order/2017/1/13 |
如果使用屬性路由的話就比較簡單了。
新建WEB API項目的話,打開App_Start目錄下的WebApiConfig.cs文件添加以下代碼開啟屬性路由配置。
1
|
config.MapHttpAttributeRoutes(); |
屬性路由也可以和公約路由混合使用,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public static void Register(HttpConfiguration config) { // Web API 配置和服務 // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi" , routeTemplate: "api/{controller}/{id}" , defaults: new { id = RouteParameter.Optional }, constraints: new { id= @"\d+" } ); } |
在要使用屬性路由的方法上打上特性標記,如下 :
1
|
[Route( "order/{UserNickName}/{ProductName}/{count}" )] |
測試結果(URL經過了編碼,不然會報400錯誤。)
通常情況下,在同一個控制器中的所有路由以相同的前綴開頭
1
2
3
|
[Route( "api/books" )] [Route( "api/books/{id:int}" )] [Route( "api/books" )] |
這樣很明顯是比較麻煩的。所以我們用[RoutePrefix]屬性來設置一個公共的前綴
測試結果
如果使用了[RoutePrefix]的話,某些比較特殊的api,我們可以使用波浪線來重寫路由前綴,如下:
測試結果(同一個類下)
路由前綴中也可以包含參數,如下
測試結果
可以在路由中添加參數約束,如下
測試結果
如果參數不是Int類型,則不會匹配到該路由
以下都是一些會被支持到的約束
可以使用多個約束,但是要用冒號分開
1
2
|
[Route( "users/{id:int:length(1,3)}" )] public User GetUserById( int id) { ... } |
結果
如果不在范圍內的話則匹配不到
自定義路由約束,需要實現IHttpRouteConstraint接口,具體查看官方
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public class NonZeroConstraint : IHttpRouteConstraint { public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary< string , object > values, HttpRouteDirection routeDirection) { object value; if (values.TryGetValue(parameterName, out value) && value != null ) { long longValue; if (value is long ) { longValue = ( long )value; return longValue != 0; } string valueString = Convert.ToString(value, CultureInfo.InvariantCulture); if (Int64.TryParse(valueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out longValue)) { return longValue != 0; } } return false ; } } |
注冊約束
1
2
3
4
5
6
7
8
9
10
|
public static class WebApiConfig { public static void Register(HttpConfiguration config) { var constraintResolver = new DefaultInlineConstraintResolver(); constraintResolver.ConstraintMap.Add( "nonzero" , typeof (NonZeroConstraint)); config.MapHttpAttributeRoutes(constraintResolver); } } |
使用約束
1
2
|
[Route( "{id:nonzero}" )] public HttpResponseMessage GetNonZero( int id) { ... } |
可選的URI參數和默認值
你可以通過添加一個問號標記路由參數使成為一個可選的URI參數。如果一個路由參數是可選的,你必須為這個方法參數定義一個默認值。
1
2
3
4
5
|
public class BooksController : ApiController { [Route( "api/books/locale/{lcid:int?}" )] public IEnumerable<Book> GetBooksByLocale( int lcid = 1033) { ... } } |
或者在路由模版中定義默認值
1
2
3
4
5
|
public class BooksController : ApiController { [Route( "api/books/locale/{lcid=1033}" )] public IEnumerable<Book> GetBooksByLocale( int lcid) { ... } } |
差不多寫這么多常用的,剩余部分自己查看官網!希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.jianshu.com/p/4430cbc57a26#