asp.net маршрутизация Web Api не работает

вот моя конфигурация маршрутизации:

config.Routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

и вот мой контроллер:

public class ProductsController : ApiController
{
    [AcceptVerbs("Get")]
    public object GetProducts()
    {
       // return all products...
    }

    [AcceptVerbs("Get")]
    public object Product(string name)
    {
       // return the Product with the given name...
    }
}

когда я пытаюсь api/Products/GetProducts/, это работает. api/Products/Product?name=test работает, а api/Products/Product/test не работает. Что я делаю не так?

обновление:

вот что я получаю, когда я пытаюсь api/Products/Product/test:

{
  "Message": "No HTTP resource was found that matches the request URI 'http://localhost:42676/api/Products/Product/test'.",
  "MessageDetail": "No action was found on the controller 'Products' that matches the request."
}

3 ответов


это из-за настроек маршрутизации и значений по умолчанию. У тебя есть два варианта.

1) путем изменения параметров маршрута в соответствии с параметром Product () в соответствии с URI.

config.Routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{action}/{name}", // removed id and used name
    defaults: new { name = RouteParameter.Optional }
);

2) другой и рекомендуемый способ-использовать правильный атрибут подписи метода.

public object Product([FromUri(Name = "id")]string name){
       // return the Product with the given name
}

Это потому, что метод ожидает параметр id при запросе api / продукты/продукт / тест а не искать имя


на основе вашего обновления:

обратите внимание:веб-API работает на основе отражения это означает, что ваши фигурные скобки {vars} должны совпадать с тем же именем в ваших методах.

поэтому, чтобы соответствовать этому api/Products/Product/test на основе этого шаблона "api/{controller}/{action}/{id}" ваш метод должен быть объявлен следующим образом:

[ActionName("Product")]
[HttpGet]
public object Product(string id){
   return id;
}

где параметр string name был заменен string id.

вот мой полный пример:

public class ProductsController : ApiController
{
    [ActionName("GetProducts")]
    [HttpGet]
    public object GetProducts()
    {
        return "GetProducts";
    }
    [ActionName("Product")]
    [HttpGet]
    public object Product(string id)
    {
        return id;
    }
}

Я попытался использовать совершенно другой шаблон:

 config.Routes.MapHttpRoute(
                name: "test",
                routeTemplate: "v2/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional, demo = RouteParameter.Optional }
            );

но с моей стороны это сработало отлично. Кстати, я дополнительно удалил [AcceptVerbs("Get")] и заменил их на [HttpGet]


ваш маршрут определяет id как параметр, но ваш метод ожидает параметр name. Я предпочитаю маршрутизацию атрибутов, если можете, затем определите /api/products/product / {name} в методе продукта.

http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2