ASP.NET Web Api: Запитаний ресурс не підтримує метод http 'GET'


92

Я маю наступну дію на ApiController:

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

І я налаштував свої маршрути таким чином:

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

У бета-версії це спрацювало чудово, але я щойно оновився до останньої версії Candidate, і тепер я бачу помилки у таких викликах:

Запитаний ресурс не підтримує метод http 'GET'.

Чому це більше не працює?

(Припускаю, що я міг би позбутися {action} і просто створити масу контролерів, але це відчуває себе безладно.)

Відповіді:


107

Якщо ви не налаштували жодного HttpMethod для своєї дії в контролері, вважається, що це лише HttpPost у RC. У бета-версії передбачається підтримка всіх методів - GET, PUT, POST та Delete. Це невелика зміна від бета-версії до RC. Ви можете легко декорувати більше однієї http-методики для своєї дії за допомогою [AcceptVerbs ("GET", "POST")].


щойно зіткнувся з цим, дякую за виправлення, але цікаво, чому я повинен робити це за допомогою власних методів, а не методу за замовчуванням "Отримати"? У мене є метод Get, який був створений шаблоном для контролера, але він не оформлений. це просто за домовленістю через назву Get?
SelAromDotNet

3
@ Джош: Так! Коли назва методу дії починається з "Отримати ...", вам не потрібно позначати його як метод GET. Детальніше читайте тут: asp.net/web-api/overview/web-api-routing-and-actions/…
Дженні О'Райлі

Я зробив, як було запропоновано у відповіді, але зараз обидва мої дзвінки, Отримати та Опублікувати, перенаправляються на Отримати дії. Будь-яка допомога, будь ласка?
Syed Ali Taqi

54

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

Ви хочете використовувати System.Web.Http, якщо це контролер веб-API.


@Eric. Дивовижно, це була причина, чому вона не працювала для мене. У мене було дієслово про мою дію, але на нього посилався через Web.Mvc, тому він не працював.
dreza


Щиро дякую, тому що System.Web.Mvc мені не підійшов.
Бурак Каракуш

34

Незважаючи на те, що це не відповідь на ОП, у мене трапилася однакова помилка із зовсім іншої першопричини; тож, якщо це допоможе комусь іншому ...

Проблемою для мене було неправильно названий параметр методу, який змусив WebAPI несподівано направити запит. У моєму ProgrammesController є такі методи:

[HttpGet]
public Programme GetProgrammeById(int id)
{
    ...
}

[HttpDelete]
public bool DeleteProgramme(int programmeId)
{
    ...
}

Запити DELETE до ... / api / programs / 3 отримували не шлях до DeleteProgramme, як я очікував, а до GetProgrammeById, оскільки DeleteProgramme не мала імені параметра з ідентифікатором. Тоді GetProgrammeById, звичайно, відхиляв ВИДАЛЕННЯ, оскільки він позначений як лише приймає GET.

Тож виправлення було простим:

[HttpDelete]
public bool DeleteProgramme(int id)
{
    ...
}

І все добре. Дурна помилка насправді, але її важко налагодити.


1
Якщо хтось використовує маршрутизацію url, спробуйте зробити, як [Route ("{programmeId = programmeId: int}")]
sree

1
Це було для мене. WebApiConfig -> MapHttpRoutes мав -> routeTemplate: "api / {controller} / {id}", тому потрібно було використовувати параметр "id".
ХокейJ

1
ваша відповідь вказала мені на мою проблему, яка була дещо іншою. Я змінив назву одного параметра [FromUri] для методу і не оновлював його на стороні клієнта
Matus

22

Якщо ви прикрашаєте свій метод HttpGet, додайте usingу верхній частині контролера наступне:

using System.Web.Http;

Якщо ви використовуєте System.Web.Mvc, тоді ця проблема може виникнути.


5
Це правда, і смішно. NET не відображає повідомлення чітко.
Teoman shipahi

15

Це, звичайно, зміна з бета-версії на RC. У прикладі, наведеному у питанні, вам тепер потрібно прикрасити свою дію за допомогою [HttpGet] або [AcceptVerbs ("GET")].

Це спричиняє проблему, якщо ви хочете змішати дії на основі дієслів (тобто "GetSomething", "PostSomething") з діями, не заснованими на дієсловах. Якщо ви спробуєте використати наведені вище атрибути, це призведе до конфлікту з будь-якою дієслівною дією у вашому контролері. Одним із способів отримати arount, це було б визначити окремі маршрути для кожного дієслова та встановити дію за замовчуванням для імені дієслова. Цей підхід можна використовувати для визначення дочірніх ресурсів у вашому API. Наприклад, такий код підтримує: "/ resource / id / children", де id та діти не є обов'язковими.

        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, щоб побачити його.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.