來源:懶得安分
鏈接:http://www.cnblogs.com/landeanfen/p/5501490.html
四、WebApi特性路由
上面說了這么多都是路由的一些全局配置。并且存在問題:
如果http請求的方法相同(比如都是post請求),并且請求的參數(shù)也相同。這個時候似乎就有點不太好辦了,這種情況在實際項目中還是比較多的。比如
public class OrderController : ApiController { //訂單排產(chǎn) [HttpPost] public void OrderProduct([FromBody]string strPostData) { } //訂單取消 [HttpPost] public void OrderCancel([FromBody]string strPostData) { } //訂單刪除 [HttpPost] public void OrderDelete([FromBody]string strPostData) { } }
這個時候如果使用我們上面講的Restful風(fēng)格的路由是解決不了這個問題的。當(dāng)然,有園友可能就說了,既然這樣,我們在路由模板里面加上“{action}”不就搞定了么!這樣確實可行。但還是那句話,不提倡。我們來看看如何使用特性路由解決這個問題。
1、啟動特性路由
如果要使用特性路由,首先在WebApiConfig.cs的Register方法里面必須先啟用特性路由:
public static void Register(HttpConfiguration config) { // 啟用Web API特性路由 config.MapHttpAttributeRoutes(); //1.默認(rèn)路由 config.Routes.MapHttpRoute( name: 'DefaultApi', routeTemplate: 'api/{controller}/{id}', defaults: new { id = RouteParameter.Optional } ); }
一般情況下,當(dāng)我們新建一個WebApi項目的時候,會自動在Register方法里面加上這句話。
2、最簡單的特性路由
我們在OrderController這個控制器里面加這個action
[Route('Order/SaveData')] [HttpPost] public HttpResponseMessage SavaData(ORDER order) { return Request.CreateResponse(); }
然后我們通過Web里面的Ajax調(diào)用
$(function () { $.ajax({ type: 'post', url: 'http://localhost:21528/Order/SaveData', data: { ID: 2, NO:'aaa'}, success: function (data, status) { alert(data); } }); });
得到結(jié)果:

當(dāng)然,有人可能就有疑義了,這個特性路由的作用和“{action}”的作用一樣嘛,其實不然,如果這里改成 [Route(“Test/AttrRoute”)] ,然后請求的url換成http://localhost:21528/Test/AttrRoute,一樣能找到對應(yīng)的action。

特性路由的目的是為了解決我們公共路由模板引擎解決不了的問題。一個action定義了特性路由之后,就能通過特性路由上面的路由規(guī)則找到。
3、帶參數(shù)的特性路由
特性路由的規(guī)則可以使用“{}”占位符動態(tài)傳遞參數(shù),比如我們有這樣一個特性路由
[Route('ordertype/{id}/order')] [HttpGet] public IHttpActionResult GetById(int id) { return Okstring>('Success' + id ); }
在瀏覽器里面調(diào)用

調(diào)用成功。到此,我們就能看懂本文最開始那個看似“怪異”的路由→/api/user/1/detail這個了。
4、參數(shù)的約束和默認(rèn)值
[Route('api/order/{id:int=3}/ordertype')] [HttpGet] public IHttpActionResult GetById(int id) { return Okstring>('Success' + id ); }
這里約束可變部分{id}的取值必須是int類型。并且默認(rèn)值是3.
看看效果


不滿足約束條件,則直接返回404。
5、路由前綴
在正式項目中,同一個控制器的所有的action的所有特性路由標(biāo)識一個相同的前綴,這種做法并非必須,但這樣能夠增加url的可讀性。一般的做法是在控制器上面使用特性[RoutePrefix]來標(biāo)識。
[RoutePrefix('api/order')] public class OrderController : ApiController { [Route('')] [HttpGet] public IHttpActionResult GetAll() { return Okstring>('Success'); } [Route('{id:int}')] [HttpGet] public IHttpActionResult GetById(int id) { return Okstring>('Success' + id ); } [Route('postdata')] [HttpPost] public HttpResponseMessage PostData(int id) { return Request.CreateResponse(); } }
那么這個這個控制器的action的時候,都需要/api/order開頭,后面接上action特性路由的規(guī)則。
五、第一個Restful風(fēng)格的WebApi服務(wù)
通過以上,我們就可以構(gòu)造一個Restful風(fēng)格的WebApi服務(wù)。
[RoutePrefix('api/AttrOrder')] public class OrderController : ApiController { [Route('')] [HttpGet] public IHttpActionResult GetAll() { return Okstring>('Success'); } [Route('{id:int=3}/OrderDetailById')] [HttpGet] public IHttpActionResult GetById(int id) { return Okstring>('Success' + id ); } [Route('{no}/OrderDetailByNo')] [HttpGet] public IHttpActionResult GetByNO(string no) { return Okstring>('Success' + no); } [Route('{name}/OrderDetailByName')] [HttpGet] public IHttpActionResult GetByName(string name) { return Okstring>('Success' + name); } [Route('postdata')] [HttpPost] public HttpResponseMessage PostData(int id) { return Request.CreateResponse(); } [Route('Test/AttrRoute')] [HttpPost] public HttpResponseMessage SavaData(ORDER order) { return Request.CreateResponse(); } }
得到結(jié)果

六、總結(jié)
整了這么久終于整完了。如果你覺得本文對你有幫助,請幫忙博主推薦,您的支持是博主最大的動力!
|