Web API - 405 - Запрошенный ресурс не поддерживает метод http 'PUT'

У меня есть проект Web API, и я не могу включить запросы "PUT/Patch" на него.

Ответ, который я получаю от скрипача:


HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Allow: GET,POST,DELETE
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcUHJvamVjdHNcZG90TmV0XFdlYkFQSVxBZFNlcnZpY2VcQWRTZXJ2aWNlXGFwaVxpbXByZXNzaW9uXDE1?=
X-Powered-By: ASP.NET
Date: Tue, 06 May 2014 14:10:35 GMT
Content-Length: 72

{"message":"The requested resource does not support http method 'PUT'."}

Исходя из вышеприведенного ответа, глаголы "PUT" не принимаются. Однако я не могу понять, где настроен соответствующий обработчик.

Метод "Put" класса объявлен следующим образом:

[HttpPatch]
[HttpPut]
public HttpResponseMessage Put(Int32 aID, [FromBody] ImpressionModel impressionModel)
{
     bla, bla, bla, bla
}

Я прочитал и внедрил изменения, описанные в следующих темах: - Веб-API Asp.NET - 405 - Глагол HTTP, используемый для доступа к этой странице, не разрешен - Как установить сопоставления обработчика - http://www.asp.net/web -api/Обзор/тестирование-и-отладка/устранение неисправностей-HTTP-405-ошибка-после-публикации-веб-API-приложения

Ничего не помогло, так как я все еще получаю ответ 405 при попытке выполнить команду "PUT" для моего проекта Web API.

Я даже закомментировал все "обработчики" в файле ApplicationsHost.config.

Работа с VS2012 Premium и IIS Express (я предполагаю, что это версия 8). Я также попробовал VS Dev Server, но это дало мне тот же результат.

У меня нет идей. Любая помощь будет оценена.

Спасибо ли

Ответ 1

Используете ли вы маршрутизацию атрибутов?

Эта мистическая ошибка была проблемой атрибутов маршрута. Это включено в вашем WebAPIConfig как:

 config.MapHttpAttributeRoutes(); 

Оказывается, Web Api Controllers "не может содержать смесь методов действий на основе глаголов и маршрутизации имен традиционных действий".; https://aspnetwebstack.codeplex.com/workitem/184

в двух словах: Мне нужно было пометить все мои действия в моем контроллере API с атрибутом [Маршрут], иначе действие будет "скрыто" (405'd) при попытке найти его через традиционную маршрутизацию.

Контроллер API:

[RoutePrefix("api/quotes")]
public class QuotesController : ApiController
{
    ...

    // POST api/Quote
    [ResponseType(typeof(Quote))]
    [Route]
    public IHttpActionResult PostQuote(Quote quote)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.Quotes.Add(quote);
        db.SaveChanges();

        return CreatedAtRoute("", new { id = quote.QuoteId }, quote);
    }

note: мой маршрут не указан, поэтому имя CreatedAtRoute() является пустой строкой.

WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

        // Web API routes
        config.MapHttpAttributeRoutes();

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

    }
}

надеюсь, что это поможет

Ответ 2

У меня была такая же проблема, как и вы, и я пробовал все, что вы пробовали, но иногда решение настолько тривиально и под носом, что вы просто не ожидаете этого и продолжаете искать более сложные причины. Убедитесь, что в URL-адресе, который вы вызываете для тестирования ваших веб-методов, имена параметров соответствуют именам в объявлении метода контроллера. Моя проблема 405 была решена, просто сделав это (я использовал параметры запроса):

Мои клиентыКонтроллер:

...

[HttpPut]
public string PutClient(string username = "", string phone= ""){...}

На моем WebApiConfig:

// Web API routes
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
     name: "DefaultApi",
     routeTemplate: "api/{controller}"
);

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

http://localhost:49216/api/clients?username=Kurt&phone=443332211

В противном случае вы получите 405 для этого метода http в этом контроллере. Мне вообще не нужно было менять web.config(нет необходимости удалять webdav и т.д.). Проверьте этот для источника в документации:

Например, рассмотрим следующее действие:

public void Get (int id)

Параметр id привязывается к URI. Следовательно, это действие может соответствовать только URI, который содержит значение для "id", либо в словаре маршрута, либо в строке запроса.

Необязательные параметры являются исключением, поскольку они являются необязательными. Для необязательный параметр, это нормально, если привязка не может получить значение из URI.

Ответ 3

Это случилось со мной, когда я изменил имя первого параметра метода PUT

public void Put(int code, [FromBody]Lead lead)

Это должно быть:

public void Put(int id, [FromBody]Lead lead)

И вот как он вызван:

$.ajax({
    type: "PUT",
    data: json,
    url: "../api/leadsapi/123",
    contentType: "application/json; charset=utf-8"
});

Ответ 4

Это также сообщение об ошибке возвращается, если вы забыли сделать метод Put() на вашем контроллере API общедоступным. Это очевидно в ретроспективе, но вызвало у меня хорошие десять минут царапин на голове.

Ответ 5

была та же проблема, мне нужно было сделать 3 вещи, чтобы решить эту проблему:

  • отключить Webdav в <modules> и <handlers>
  • Убедитесь, что HttpPut находится из System.Web.Http, а не из System.Web.Mvc при использовании WebAPI
  • включить ExtensionlessUrlHandler следующим образом

<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />

<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />

<remove name="ExtensionlessUrlHandler-Integrated-4.0" />

<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />

<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

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

Ответ 6

Этот ответ исправил проблему для меня. Мне пришлось добавить атрибут Route, и проблема была решена.

    [HttpPut]
    [Route("")]
    public HttpResponseMessage MyMethod()

Ответ 7

Вы должны настроить его в конфигурации веб-серверов. Это зависит от типа веб-сервера, где вы можете это сделать. Например, IIS, вы можете использовать файл web.config для этого в своем корневом каталоге документа. По запросам на перекрестный поиск вам нужно добавить заголовки CORS в ответ, чтобы разрешить происхождение, методы и т.д.

note: Возможно, вы можете сделать что-то об этом с помощью структуры ASP.NET, но я думаю, что это не похоже на.

Ответ 8

Добавьте следующий раздел в разделе Обработчик в web.config:

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,PATCH,MERGE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

Например:

<handlers>
    <remove name="WebDAV" />
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <remove name="TRACEVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,PATCH,MERGE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

Ответ 9

Может быть, сейчас поздно, но кто-то может использовать это.

Я хотел использовать запрос PUT, и я только что отправил строковый объект в web api, а метод put только принял этот объект.

Jquery

let musterija = {
            Name: name,
            Email: email,
            Password: password,
            Username: logUser.Username,
            Lastname: lastname,
            GenderString: gender,
            Jmbg: identification,
            PhoneNumber: phone,
        };

        $.ajax({
            method: "PUT",
            url: "/api/Musterija",
            data: JSON.stringify(musterija),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function () {
                alert("Entity updated");
                EmptyAllInputs();
                $('#divprofile').show();
                $('#divupdate').hide();
            },
            error: function (msg) {
                alert("Fail - " + msg.responseText);
            }
        });

WEB API

    [HttpPut]
    public HttpResponseMessage PutMusterija(Musterija m)

Ответ 10

Для меня это было так, как утверждали многие другие постеры. Скорее всего, у вас все правильно настроено в webapiconfig, однако вы просто упускаете что-то глупое.

В моем случае у меня был маршрут, определенный как:

[HttpPut]
    [Route("api/MilestonePut/{Milestone_ID}")]
    public void Put(int id, [FromBody]Milestone milestone)
    {
        db.Entry(milestone).State = System.Data.Entity.EntityState.Modified;
        db.SaveChanges();
    }

Видишь проблему? Параметр определяется как Milestone_ID в маршруте, но как идентификатор в самой функции. Вы могли бы подумать, что .NET был бы достаточно умен, чтобы понять это, но это определенно не так и не будет работать.

Однажды я изменил его, чтобы он соответствовал параметру, например

[HttpPut]
    [Route("api/MilestonePut/{id}")]
    public void Put(int id, [FromBody]Milestone milestone)
    {
        db.Entry(milestone).State = System.Data.Entity.EntityState.Modified;
        db.SaveChanges();
    }

все работало как шарм.