Как определить метод PUT при маршрутизации только ограничение методов Put в контроллере без параметра?

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

config.Routes.MapHttpRoute(
    name: "DefaultApiPut",
    routeTemplate: "api/{controller}",
    defaults: new { httpMethod = new HttpMethodConstraint(HttpMethod.Put) }
);


config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get, HttpMethod.Post, HttpMethod.Delete) }
);

Вот мой контроллер:

public class MyController : ApiController {
    [HttpPut]
    public void Put()
    {
        //blah
    }
}

Как-то, когда клиент передает запрос PUT с URL /api/myController/12345, он по-прежнему сопоставляется методу Put в MyController, я ожидаю, что ошибка, подобная ресурсу, не найдена.

Как заставить метод Put принимать запрос без параметра?

Спасибо заранее!

Ответ 1

Вы помещаете ограничение httpMethod в defaults, но оно должно быть в constraints.

defaults просто говорит, что будут значения по умолчанию, если запрос не включает некоторые или все из них в качестве параметров маршрутизации (что в случае глагола не имеет смысла, поскольку каждый HTTP-запрос всегда имеет глагол как часть протокола). constraints ограничить комбинацию значений маршрута, которые активируют маршрут, и это то, что вы на самом деле пытаетесь сделать.

FYI, для этой простой/стандартной маршрутизации вам не нужен атрибут [HttpPut] в контроллере API. Это уже обрабатывается HTTP-маршрутизацией, которая сопоставляет глагол методу контроллера.

Ответ 2

Это работает для ограничения метода http на маршрутах:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
    config.Routes.MapHttpRoute(
       name: "LocationApiPOST",
       routeTemplate: "api/{orgname}/{fleetname}/vehicle/location",
       defaults: new { controller = "location" }
       constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) }
   );

    config.Routes.MapHttpRoute(
       name: "LocationApiGET",
       routeTemplate: "api/{orgname}/{fleetname}/{vehiclename}/location/{start}",
       defaults: new { controller = "location", start = RouteParameter.Optional }
       constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
   );

   ...

}