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.