問題
如何為路由中參數設置默認值。
解決方案
不管使用屬性路由還是集中式路由,ASP.NET WEB API 都可以很方便的為路由定義默認參數。在每次客戶端請求的時候,如果客戶端沒有傳這些參數,框架會自動給他們賦值。
對于集中式路由,MapHttpRoute 擴展方法接收默認值使用的是第三個參數 IDictionary<string,object> 的形式(也是一個匿名類)。Key(或者匿名對象的屬性)必須與路由模板中參數名稱一致。
config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new {id = VALUE} );
在屬性路由中,直接在屬性聲明中定義默認值。
[Route("items/{id:int=VALUE}")] public HttpResponseMessage Get(int id) { }
最后,對于這兩種類型的路由,也可以為 Action 簽名提供默認值。
public HttpResponseMessage Get(int id = VALUE) { }
工作原理
當我們使用集中式路由的時候,聲明在路由上的默認值被用于 IHttpRpute 的對象,在客戶端調用中忽略了一些請求路由參數的情況下,都是調用 Request.GetRouteData 方法(我們顯示的調用或被框架調用)來補全這些默認值。
對于屬性路由,除了一些額外的注冊步驟,處理上也是一樣的。應用程序啟動的時候,所有路由屬性都被處理成 RouteEntry 實例。這是通過每個在 Controller 和 Action 上的屬性路由上調用 CreateRoute 方法來完成的。CreateRoute 會在內部調用 DirectRouteFactoryContext 的 CreateBuilder 方法。InlineRouteTemplateParser 是用來解析定義在路由屬性中的路由模板、處理相關約束、以及默認值。然后,路由的注冊就像是集中式路由的默認值和約束。
代碼演示
如代碼片段 3-7 所示例子
代碼片段 3-7. 路由默認值的簡單使用
// 集中式路由 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "{controller}/{id}", defaults: new {id = 100} );
// 屬性路由 [Route("items/{id:int=100}")] public HttpResponseMessage Get(int id) { }
// 方法內的默認值 public HttpResponseMessage Get(int id = 100) { }
在上面的例子中,下面兩個請求都是一樣的,返回的都是 Id 為 100 的數據:
- myapi.com/items/
- myapi.com/items/100
注意事項 默認路由的使用是一種“貪心”路由,在上面的例子中,就不能在不使用參數的情況下獲取所有的數據。
文章列表