ASP.NET Web Api: запрашиваемый ресурс не поддерживает метод http 'GET'
У меня есть следующее действие на ApiController:
public string Something()
{
return "value";
}
И я настроил свои маршруты следующим образом:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
В бета-версии это сработало отлично, но я только что обновился до последнего кандидата, и теперь я вижу ошибки в таких вызовах:
Запрошенный ресурс не поддерживает метод http 'GET'.
Почему эта работа больше не работает?
(я полагаю, я мог бы избавиться от {action} и просто сделать тонну контроллеров, но это кажется грязным.)
Ответы
Ответ 1
Если вы не настроили HttpMethod в своем действии в контроллере, предполагается, что это только HttpPost в RC. В Beta предполагается, что он поддерживает все методы - GET, PUT, POST и Delete. Это небольшое изменение от бета-версии до RC. Вы можете легко декорировать более одного метода http вашего действия с помощью [AcceptVerbs ( "GET", "POST" )].
Ответ 2
Вся приведенная выше информация верна, я также хотел бы отметить, что аннотация [AcceptVerbs()]
существует как в пространствах имен System.Web.Mvc, так и в System.Web.Http.
Вы хотите использовать System.Web.Http, если это контроллер веб-API.
Ответ 3
Хотя это не ответ на ОП, у меня была такая же ошибка из совершенно другой основной причины; поэтому в случае, если это поможет кому-то еще...
Проблема для меня была некорректно названным параметром метода, который заставил WebAPI направить запрос неожиданно. У меня есть следующие методы в моем ProgrammesController:
[HttpGet]
public Programme GetProgrammeById(int id)
{
...
}
[HttpDelete]
public bool DeleteProgramme(int programmeId)
{
...
}
Запросы DELETE для... /api/programs/ 3 не были перенаправлены на DeleteProgramme, как я ожидал, но в GetProgrammeById, потому что у DeleteProgramme не было имени параметра id. GetProgrammeById тогда, конечно, отклонял DELETE, поскольку он помечен как только прием GET.
Итак, исправление было простым:
[HttpDelete]
public bool DeleteProgramme(int id)
{
...
}
И все хорошо. Глубокая ошибка действительно, но трудно отлаживать.
Ответ 4
Это, безусловно, изменение от Beta до RC. В примере, представленном в вопросе, теперь вам нужно украсить свое действие с помощью [HttpGet] или [AcceptVerbs ( "GET" )].
Это вызывает проблему, если вы хотите смешивать действия на основе глагола (т.е. "GetSomething", "PostSomething" ) с действиями на основе не глагола. Если вы попытаетесь использовать приведенные выше атрибуты, это вызовет конфликт с любым действием на основе глагола в вашем контроллере. Один из способов получить arount, который будет определять отдельные маршруты для каждого глагола, и установить действие по умолчанию на имя глагола. Этот подход может использоваться для определения дочерних ресурсов в вашем API. Например, следующий код поддерживает: "/resource/id/children", где id и children являются необязательными.
context.Routes.MapHttpRoute(
name: "Api_Get",
routeTemplate: "{controller}/{id}/{action}",
defaults: new { id = RouteParameter.Optional, action = "Get" },
constraints: new { httpMethod = new HttpMethodConstraint("GET") }
);
context.Routes.MapHttpRoute(
name: "Api_Post",
routeTemplate: "{controller}/{id}/{action}",
defaults: new { id = RouteParameter.Optional, action = "Post" },
constraints: new { httpMethod = new HttpMethodConstraint("POST") }
);
Надеемся, что будущие версии Web API будут лучше поддерживать этот сценарий. В настоящее время проблема запускается в проекте aspnetwebstack codeplex, http://aspnetwebstack.codeplex.com/workitem/184. Если это то, что вы хотели бы видеть, пожалуйста, проголосуйте по этому вопросу.
Ответ 5
Если вы украшаете свой метод с помощью HttpGet
, добавьте следующий using
в верхней части контроллера:
using System.Web.Http;
Если вы используете System.Web.Mvc
, эта проблема может возникнуть.
Ответ 6
Та же проблема, что и выше, но сильно отличающийся корень. Для меня это было то, что я попал в конечную точку с правилом перезаписи https. Нажатие на http вызвало ошибку, работало, как ожидалось, с помощью https.
Ответ 7
Иметь ту же настройку, что и OP.
Один контроллер со многими действиями... менее "грязный": -)
В моем случае я забыл "[HttpGet]" при добавлении нового действия.
[HttpGet]
public IEnumerable<string> TestApiCall()
{
return new string[] { "aa", "bb" };
}