2014-11-21 3 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. –

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 } 
    ); 
Смежные вопросы