[水煮 ASP.NET Web API2 方法論](3-2)直接式路由/屬性路由

來源:互聯網
上載者:User

標籤:維護   service   邏輯   相同   開發人員   ted   int   命名   play   

問題

怎麼樣可以使用更貼近資源(Controller,Action)的方式定義路由。

 

解決方案

可以使用屬性路由直接在資源層級聲明路由。只要簡單的在 Action 上使用屬性路由 RouteAttribute,然後傳一個相關路由模板就可以。屬性路由與集中式路由在路由模板含義上基本是一樣的,所有路由參數應該使用花括弧,同時要與使用的 Action 相匹配。直接式路由支援預設路由,選擇性參數,約束。詳細分析請往下走。

1 [Route("api/teams/{id}")]2 public Team GetTeam(int id)3 {4     //忽略邏輯5 }

 

要是啟用屬性路由的話,需要在應用程式啟動的位置,使用 HttpConfiguration 調用 MapAttributeRoutes 的擴充方法。

Config.MapHttpAttributeRoutes();

 

工作原理

一個叫做 Attribute Routing 的開源類庫已經成為了 ASP.NET WEB API 2 架構的核心部分。隨之而來的是,解決了集中式路由在維護上給我們帶來的痛苦,允許我們直接在 Controller 和 Action 上聲明路由。

 

對於大多數開發人員來說,與集中式路由相比,屬性路由(上面所說的直接路由)是更加自然的方法,屬性路由強調的是 WEB API 資源和 URI 之間的直接關係,URI 資源應該是可以通過 HTTP 直接存取。事實上,還是有一些流行的 .NET Web 架構,例如,ServiceStack、NancyFx 都有自己的方式來定義這種貼近資源的路由(嵌入資源)。

 

在應用程式啟動時,調用 MapHtpAtrributeRoutes,其實是告訴 ASP.NET WEB API 掃描所有 Controller 上聲明的屬性路由。

 

究其緣由,屬性路由的聲明和集中式路由沒有太大的區別。而且,他們的路由都是被添加到與前面上一篇集中式路由程式碼片段 3-1 一樣的路由集合中。最大的不同就是,直接式路由(屬性路由)是作為單一複合路由(內部的 SubRouteCollection 類型)被添加到路由集合中的,使用的路由 key 是 MS_attributerouteWebApi。

 

處理每個屬性路由的時候,Controller(HttpControllerDescriptor)或 Action(HttpActionDescriptor)會標記出能夠訪問到的屬性路由。這個過程的完成是通過在這些 descriptor 類型的 Properties 字典中添加 MS_IsAttributeRouted。

 

屬性路由提供了一些路由自訂處理。事實上,不必強制在 Controller 和 Action 上使用 RouteAttribue 聲明路由。通過實現 IDirectRouteFactory,可以自訂屬性路由、甚至無屬性路由,集中式邏輯路由。IDirectRouteFactory 的使用 和 IDirectRouteProvider 會在後面的 3-11 篇和 6-8 篇的時候再次討論。

 

代碼示範

與集中式路由相反,屬性路由顯得很自然,直接展示了 Controller 和 Action 之間的關係,也很容易聲明複雜的路由。如程式碼片段 3-4 例子所示。

 

程式碼片段 3-4. 聲明簡單的屬性路由

 1 public class TeamsController : ApiController 2 { 3     [Route("api/teams/{id}")] 4     public Team GetTeam(int id) 5     { 6         //忽略邏輯 7     } 8   9     [Route("api/teams")]10     public IEnumerable<Team> GetTeams()11     {12         //忽略邏輯13     }14  15     [Route("api/teams/{teamId}/players")]16     public IEnumerable<Player> GetPlayers(int teamId)17     {18         //忽略邏輯19     }20 }

 

屬性路由也允許通過 RoutePrefixAttribute 定義路由首碼。但,只能在 Controller 層級聲明,修改程式碼片段 3-4,為這個 Controller 中所有的路由定義一個公用首碼。使用 RoutePrefixAttribute 重寫,如程式碼片段 3-5 所示。需要注意的是,當路由被顯示的時候,所有在 Action 上指定的 RouteAttribute 是路由模板的一部分,被拼接在 RoutePrefixAttribute 之後。

 

程式碼片段 3-5. 屬性路由和路由首碼

 1 [RoutePrefix("api/teams")] 2 public class TeamsController : ApiController 3 { 4     [Route("{id}")] 5     public Team GetTeam(int id) 6     { 7         // 忽略邏輯 8     } 9  10     [Route]11     public IEnumerable<Team> GetTeams()12     {13         // 忽略邏輯14     }15  16     [Route("{teamId}/players")]17     public IEnumerable<Player> GetPlayers(int teamId)18     {19         // 忽略邏輯20     }21 }

 

與集中式路由相同的是,屬性路由也是依賴 HTTP 謂詞分發。所以,由於對路由定義命名的約定(上一篇描述了 HTTP 謂詞分發),程式碼片段 3-4 和 3-5 只能處理 HTTP GET 請求。

 

為了可以支援其他 HTTP 謂詞類型,再在 Controller 中加幾個 Action ,命名的時候,首碼使用 HTTP 謂詞相關的動詞或者標籤。程式碼片段 3-6 有 POST 和 PUT 兩個類型的 Action。他們都擴充了 TeamsController 的功能,可以建立 Team 資源,建立一個 Player 資源到一個給定的 Team 中,這兩個都是 POST,以及一個更新 Team 的操作(PUT)。

 

程式碼片段 3-6. 補充定義,支援其他的 HTTP 謂詞

 1 [Route] 2 public HttpResponseMessage PostTeam(Team team) 3 { 4     // 忽略邏輯 5 } 6 [HttpPost] 7 [Route("{teamId}/players")] 8 public HttpResponseMessage AddPlayer(int teamId, Player player) 9 {10     // 忽略邏輯11 }12 [Route("{id}")]13 public HttpResponseMessage PutTeam(int id, Team team)14 {15     // 忽略邏輯16 }

 

[水煮 ASP.NET Web API2 方法論](3-2)直接式路由/屬性路由

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.