ASP.NET Web Api: запрошенный ресурс не поддерживает HTTP-метод 'GET'

93

У меня есть следующее действие с ApiController:

public string Something()
{
    return "value";
}

И я настроил свои маршруты следующим образом:

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

В бета-версии это работало нормально, но я только что обновился до последней версии Release Candidate и теперь вижу такие ошибки при вызовах, как это:

Запрошенный ресурс не поддерживает HTTP-метод GET.

Почему это больше не работает?

(Полагаю, я мог бы избавиться от {action} и просто сделать тонну контроллеров, но это кажется беспорядочным.)

Джош Шульц
источник

Ответы:

108

Если вы не настроили какой-либо HttpMethod для своего действия в контроллере, предполагается, что это будет только HttpPost в RC. В бета-версии предполагается поддержка всех методов - GET, PUT, POST и Delete. Это небольшое изменение от беты к RC. С помощью [AcceptVerbs ("GET", "POST")] вы можете легко удалить более одного http-метода для своего действия.

Динеш Равва
источник
только что столкнулся с этим, спасибо за исправление, но любопытно, почему я должен делать это с моими собственными методами, а не методом "Get" по умолчанию? У меня есть метод Get, созданный шаблоном для контроллера, но он не оформлен. это просто по соглашению из-за имени Get?
SelAromDotNet
3
@ Джош: Да! Когда имя метода действия начинается с «Get ...», вам не нужно отмечать его как метод GET. Подробнее читайте здесь: asp.net/web-api/overview/web-api-routing-and-actions/…
Дженни О'Рейли
Я сделал, как было предложено в ответе, но теперь оба моих вызова, Get и Post, перенаправляются на Get Action. Любая помощь, пожалуйста?
Сайед Али Таки
55

Вся приведенная выше информация верна, я также хотел бы отметить, что [AcceptVerbs()]аннотация существует как в пространствах имен System.Web.Mvc, так и в System.Web.Http.

Вы хотите использовать System.Web.Http, если это контроллер веб-API.

Эрик
источник
@ Эрик. Круто, вот почему у меня это не сработало. У меня был глагол для моего действия, но на него ссылались через Web.Mvc, поэтому он не работал.
dreza
Отлично, Ты спас мне день
Хоссейн Наримани Рад
Большое спасибо, потому что System.Web.Mvc мне не подошел.
Burak Karakuş
34

Хотя это не ответ на OP, у меня была точно такая же ошибка с совершенно другой основной причиной; так что, если это поможет кому-то еще ...

Проблема для меня заключалась в неверно названном параметре метода, из-за которого 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)
{
    ...
}

И все хорошо. Это действительно глупая ошибка, но ее трудно отладить.

Карл Шарман
источник
1
Если кто-то использует маршрутизацию URL-адресов, попробуйте сделать что-то вроде [Route ("{programmeId = programmeId: int}")]
sree 05
1
Это было для меня. WebApiConfig -> MapHttpRoutes имел -> routeTemplate: "api / {controller} / {id}", поэтому необходимо было использовать параметр 'id'.
HockeyJ
1
Ваш ответ указал мне на мою проблему, которая немного отличалась. Я изменил имя одного параметра [FromUri] для метода и не обновлял его на стороне клиента
Матус
22

Если вы украшаете свой метод HttpGet, добавьте usingв верхнюю часть контроллера следующее:

using System.Web.Http;

Если вы используете System.Web.Mvc, то может возникнуть эта проблема.

Сохаил xIN3N
источник
5
Это правда, и, как ни странно, .NET не показывает четкое сообщение.
Теоман Шипахи
15

Это, безусловно, переход от бета-версии к RC. В примере, приведенном в вопросе, теперь вам нужно украсить свое действие с помощью [HttpGet] или [AcceptVerbs ("GET")].

Это вызывает проблему, если вы хотите смешивать действия на основе глаголов (например, «GetSomething», «PostSomething») с действиями, не основанными на глаголах. Если вы попытаетесь использовать указанные выше атрибуты, это вызовет конфликт с любым действием на основе глагола в вашем контроллере. Один из способов возбудиться, это определить отдельные маршруты для каждого глагола и установить действие по умолчанию для имени глагола. Этот подход можно использовать для определения дочерних ресурсов в вашем 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") }
        );

Надеюсь, будущие версии веб-API будут лучше поддерживать этот сценарий. В настоящее время в проекте aspnetwebstack codeplex, http://aspnetwebstack.codeplex.com/workitem/184 зарегистрирована проблема . Если вы хотели бы это увидеть, пожалуйста, проголосуйте по этому вопросу.

Джереми
источник
8

Используйте ту же настройку, что и OP. Один контроллер с множеством действий ... менее "беспорядочный" :-)

В моем случае я забыл «[HttpGet]» при добавлении нового действия.

[HttpGet]
public IEnumerable<string> TestApiCall()
{
    return new string[] { "aa", "bb" };
}
Шаакир
источник
6

Та же проблема, что и выше, но корень сильно отличается. Для меня это было то, что я попал в конечную точку с правилом перезаписи https. Нажатие на http вызвало ошибку, работало как ожидалось с https.

Верн Д.
источник
3

Замените следующий код в этом пути

Путь :

App_Start => WebApiConfig.cs

Код:

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}/{Param}",
            defaults: new { id = RouteParameter.Optional,
                            Param = RouteParameter.Optional }
                          );
Казем Малеки
источник
1

Я не знаю, может ли это быть связано с сообщением OP, но мне не хватало аннотации [HttpGet], и это было причиной ошибки, как указано в методах @dinesh_ravva, по умолчанию предполагается, что это HttpPost.

Пьеррик Мартельер
источник
0

Моя проблема была так же проста, как наличие нулевой ссылки, которая не отображалась в возвращенном сообщении, мне пришлось отлаживать свой API, чтобы увидеть ее.

Ninos
источник