2014-11-21 46 views
0

我有這個WebAPI控制器,有2種方法。這個控制器更像是一種實用型控制器,並不是真正專注於某種類型的實體,就像大多數示例和鍋爐板模板會產生的一樣。反正,我的2個方法是這樣的:Web Api 2.0路由 - 多個動作匹配

// api/Custom/SayHello 
    [HttpGet] 
    public async Task<string> SayHello() 
    { 

     return await Task.FromResult("Hello World Async").ConfigureAwait(false); 
    } 

    // api/Custom/SayFloat 
    [HttpGet] 
    public async Task<float> SayFloat() 
    { 

     return await Task.FromResult(1000.0f).ConfigureAwait(false); 
    } 

而且我已經經歷了很多路由模板組合的走了,我最新的一個是這樣的:

 config.Routes.MapHttpRoute("DefaultApiWithId", 
      "Api/{controller}/{id}", 
      new { id = RouteParameter.Optional }); 

     /* ----- this is trying to match my utility controller and its actions ----- */ 
     config.Routes.MapHttpRoute(
       name: "ActionApi", 
       routeTemplate: "Api/{controller}/{action}" 
      ); 

我得到這個錯誤:發現多個操作符合請求....

所以我當前的「解決方法」是爲每個要公開的實用程序創建一個控制器。我在想,有一些我沒有嘗試過的路由模板。有任何想法嗎?

回答

4

這個問題的其他答案是正確的。不過,我想提供一個我很喜歡的替代品,Attribute Routing

The first release of Web API used convention-based routing. In that type of routing, you define one or more route templates, which are basically parameterized strings. When the framework receives a request, it matches the URI against the route template.

另一方面,通過屬性路由,您可以使用屬性修飾您的控制器和操作,從而實現更靈活的路由方案。

[Route("api/custom")] 
public class CustomController : ApiController 
... 
// api/Custom/SayHello 
[Route("SayHello")] 
[HttpGet] 
public async Task<string> SayHello() 
{ 
    return await Task.FromResult("Hello World Async").ConfigureAwait(false); 
} 

// api/Custom/SayFloat 
[Route("SayFloat")] 
[HttpGet] 
public async Task<float> SayFloat() 
{ 
    return await Task.FromResult(1000.0f).ConfigureAwait(false); 
} 
+0

我同意,如果您使用WebApi2,屬性路由是最好的方法。 – 2014-11-21 10:14:17

1

的Web API將匹配它發現的順序的路線,所以你需要改變你的路由的順序:

config.Routes.MapHttpRoute(
    name: "ActionApi", 
    routeTemplate: "Api/{controller}/{action}" 
    ); 

config.Routes.MapHttpRoute(
    name: "DefaultApi", 
    routetemplate "Api/{controller}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
    ); 

一個字的警告,雖然,這將停止defaultapi路線與合作ID參數。我可能更好地明確聲明你的控制器:

config.Routes.MapHttpRoute(
    name: "ActionApi", 
    routeTemplate: "Api/Custom/{action}", 
    defaults: new { controller = "Custom" } 
    ); 

config.Routes.MapHttpRoute(
    name: "DefaultApi", 
    routetemplate "Api/{controller}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
    );