您好,登錄后才能下訂單哦!
WebApi2默認(rèn)的路由規(guī)則我們稱作基于約定路由,很多時(shí)候我們使用RESTful風(fēng)格的URI.簡單的路由是沒問題的,如 api/Products/{id},但有些事很難處理的,如資源之間存在嵌套關(guān)系:客戶包含訂單,書有作者屬性等等。對(duì)于這種Uri,我們希望的路由是這樣的:/costomers/{customerid}/orders 或 /costomers/{customerid}/orders/{orderid}
考慮到這只是某個(gè)Controller的路由格式,而我們會(huì)有很多個(gè)Controller,用基于約定路由顯然不合適(要配置很多的路由)
使用特性路由就簡單了,在action上加一個(gè)特性即可
[Route("customers/{customerId}/orders")]public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }
通過使用特性路由,我們還可以做API的版本控制
/api/v1/products
/api/v2/products
啟用特性路由需要在配置過程中調(diào)用System.Web.HttpConfigurationExtensions類的MapHttpAttributeRoutes方法
using System.Web.Http;namespace WebApplication { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API routes config.MapHttpAttributeRoutes(); // Other Web API configuration not shown. } } }
在WebApi1中 項(xiàng)目模板是這樣的
protected void Application_Start() { WebApiConfig.Register(GlobalConfiguration.Configuration); //。。。}
如果要啟用特性路由,需要改成如下代碼
protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); //。。。}
注:特性路由和基于約定路由是可以結(jié)合使用大的。
HttpMethod
默認(rèn)情況,WebApi會(huì)根據(jù)action的方法名前綴查找action(不區(qū)分大小寫),比如GetUsers,會(huì)匹配Get。通過在action上添加HttpMethod特性,可以覆蓋action需要映射的Http Method。
可使用的特性包括:[HttpDelete],[HttpPost],[HttpHead],[HttpOptions],[HttpPatch],[HttpGet],[HttpPut]
通過AcceptVerbs特性,我們還可以指定非標(biāo)準(zhǔn)方法以及多個(gè)方法,如 [AcceptVerbs("MKCOL","GET","POST")]
通常情況下,一個(gè)Controller下的action會(huì)使用相似的路由模板,如
[Route("api/books")]
[Route("api/books/{id:int}")]
[Route("api/books/{bookid}/authors")]
這時(shí)候可以為整個(gè)controller指定[RoutePrefix]特性,以使用共同的前綴,把[RoutePrefix("/api/books")]加到controller上,action的路由特性就變成這樣:
[Route("")]
[Route("{id:int}")]
[Route("{bookid}/authors")]
此外,路由前綴中也可以包含參數(shù),如[RoutePrefix("api/{userid}/books")]
這里還有兩個(gè)小技巧
如果有某個(gè)特殊路由不希望使用前綴,可以在路由中添加~,如[Route("~api/otherbooks")]
有時(shí)候需要幾個(gè)路由片段結(jié)合起作用,如日期 /api/books/date/2013/06/17
這時(shí)候就需要使用字符* ,[Route("date/{*date:datetime:regex(\\d{4}/\\d{2}/\\d{2})}")],不過這種參數(shù)只能用作路由的最后一個(gè)參數(shù)
路由約束讓我們可以限制模板參數(shù)的匹配方式。一般的語法是 "{參數(shù):約束類型}":
[Route("users/{id:int}"]public User GetUserById(int id) { ... } [Route("users/{name}"]public User GetUserByName(string name) { ... }
如果參數(shù)int,則選中第一個(gè)GetUserById,否則是GetUserByName。(跟方法定義的順序無關(guān))
下面的表格列出了支持的約束
約束 | 介紹 | 示例 |
---|---|---|
alpha | 匹配大寫或小寫字母 (a-z, A-Z) | {x:alpha} |
bool | {x:bool} | |
datetime | {x:datetime} | |
decimal | {x:decimal} | |
double | {x:double} | |
float | 匹配一個(gè) 32位浮點(diǎn)數(shù) | {x:float} |
guid | {x:guid} | |
int | {x:int} | |
length | 匹配一個(gè)長度在指定范圍內(nèi)的字符串 | {x:length(6)} {x:length(1,20)} |
long | {x:long} | |
max | 匹配指定了最大值的整數(shù) | {x:max(10)} |
maxlength | 匹配指定了最大長度字符串 | {x:maxlength(10)} |
min | 匹配指定了最小值的整數(shù) | {x:min(10)} |
minlength | 匹配指定了最小長度字符串 | {x:minlength(10)} |
range | 匹配指定了大小區(qū)間的整數(shù) | {x:range(10,50)} |
regex | 匹配一個(gè)正則表達(dá)式 | {x:regex(^\d{3}-\d{3}-\d{4}$)} |
如果要指定多個(gè)約束,需要用冒號(hào)間隔 [Route("users/{id:int:min(1)}")]
通過實(shí)現(xiàn)IHttpRouteConstraint接口,還可以創(chuàng)建自定義路由約束。(不過一般正則就可以搞定了)
還可以通過實(shí)現(xiàn)IInlineConstraintResolver接口替換整個(gè)DefaultInlineConstraintResolver類。這樣做將取代所有的內(nèi)置的約束,除非實(shí)現(xiàn)IInlineConstraintResolver的類將它們添加進(jìn)去。
自定義路由約束Demo
通過在參數(shù)約束后面添加一個(gè)問號(hào),可以設(shè)定URI參數(shù)是可選的;也可以像普通方法那樣指定默認(rèn)值:
[Route("api/books/locale/{lcid:int?}")]public IEnumerable<Book> GetBooksByLocale(int lcid = 1033) { ... }
[Route("api/books/locale/{lcid:int=1033}")]public IEnumerable<Book> GetBooksByLocale(int lcid) { ... }
這兩者是等價(jià)的
WebApi中,每一個(gè)路由都有一個(gè)名字,用于生成鏈接,并在放入Http響應(yīng)中。(應(yīng)該是用于重定向吧)
例如對(duì)某個(gè)action A指定Name,[Route("api/books/{id}", Name="GetBookById")]
那么其他action B在需要返回這個(gè)action A的鏈接時(shí),就可以這樣使用
public HttpResponseMessage Post(Book book) { var response = Request.CreateResponse(HttpStatusCode.Created); string uri = Url.Link("GetBookById", new { id = book.BookId }); response.Headers.Location = new Uri(uri); return response; }
路由順序
通過設(shè)定特性[Route("xxx",RouteOrder=n)]可以指定路由的查找順序
[Route("pending", RouteOrder = 1)]public HttpResponseMessage GetPending() { ... }
不過意義不大,通過順序來控制,還不如設(shè)定更好的路由來的實(shí)際,而且不至于讓開發(fā)人員覺得混亂。
http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#order
翻譯:
http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
(注):相關(guān)文檔請(qǐng)看https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。