Удаление WebAPI не работает - метод 405 запрещен


120

Я ценю любую помощь в этом вопросе, так как сайт должен заработать сегодня вечером!

У меня есть веб-контроллер api с методом удаления. Метод отлично работает на моем локальном компьютере под управлением IIS Express (Windows 8), но как только я развернул его на активном сервере IIS (Windows Server 2008 R2), он перестал работать и выдает следующее сообщение об ошибке:

Ошибка HTTP 405.0 - метод не разрешен. Страница, которую вы ищете, не может быть отображена из-за использования недопустимого метода (HTTP-команда)

Я поискал в Интернете решения и реализовал самые разумные из них. Моя веб-конфигурация имеет следующие настройки:

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
<handlers>
    <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" />
</handlers>
</system.webServer>

Я также пытался изменить сопоставления обработчиков и фильтрацию запросов в IIS, но безрезультатно. Обратите внимание, что правила создания WebDAV в IIS, похоже, отключены.

Мы будем очень благодарны за любые идеи.

Ответы:


199

В конце концов я нашел решение! Если вы столкнетесь с той же проблемой, добавьте следующее в свой web.config

<system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/> <!-- ADD THIS -->
    </modules>
    ... rest of settings here

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


2
Мне также пришлось добавить удаление в раздел обработчиков согласно stackoverflow.com/a/6698096/254156
rrrr

3
Также здесь работал. Но может ли кто-нибудь объяснить мне отношение к WebDAVModule?
Боас Энклер

11
для тех, кто просто копирует и вставляет: runAllManagedModulesForAllRequests = "true" на самом деле не нужен и может сломать другие вещи.
Зар Шардан

В некоторых других публикациях в Интернете предлагается удалить модуль с помощью раздела «Модули IIS», это отключает его, но по-прежнему вызывает эту / аналогичную проблему, это самый надежный метод
Энтони Мэйн

4
@ZarShardan (и другие) К вашему сведению: если вы удалите атрибут runAllManagedModulesForAllRequests = "true", вам также необходимо будет добавить <remove name = "WebDAV" /> под узлом <handlers>.
Аарон

65

В некоторых случаях удаление его только из модулей может привести к следующей ошибке:

500.21 Обработчик "WebDAV" имеет неверный модуль "WebDAVModule" в своем списке модулей.

Модуль: Уведомление веб-ядра IIS: ExecuteRequestHandler "

решение было предложено здесь . Также нужно удалить его из обработчиков.

<system.webServer>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
    <handlers>
        <remove name="WebDAV" />
    </handlers>
</system.webServer>

1
это работает для меня, но может ли кто-нибудь пролить свет на то, что на самом деле представляет собой WebDAV?
Назрул Мухаймин

31

В моем случае ни одно из вышеперечисленных решений не помогло. Это произошло потому, что я изменил имя параметра в моем Deleteметоде.

я имел

public void Delete(string Questionid)

вместо того

public void Delete(string id)

Мне нужно использовать это idимя, потому что оно объявлено в моем WebApiConfigфайле. Обратите внимание на idимя в третьей и четвертой строках:

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

Я получил это решение отсюда .


15

DELETEГлагол Javascript для HTTP должен быть таким:

$.ajax({
    **url: "/api/SomeController/" + id,**
    type: "DELETE",
    dataType: "json",
    success: function(data, statusText) {
        alert(data);
    },
    error: function(request, textStatus, error) {
        alert(error);
        debugger;
    }
});

Вы не использовать что - то вроде этого:

...
data: {id:id}
...

как при использовании POSTметода.


1
Привет, @Pavel, это правильно, если вы действительно используете полностью RESTful-реализацию. К сожалению, не все делают это, и довольно часто можно увидеть разработчиков, использующих POST вместо DELETE и т. Д. Спасибо за пояснение.
Крис

5

После того, как я попробовал почти все решения здесь, это сработало для меня. Добавьте это в свой файл конфигурации API

<system.webServer>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
</system.webServer>

Пробовал много чего, это сработало. .NET версии 4.6.1 - Спасибо.
Кетан

4

Если вы используете IIS 7.0 или более позднюю версию. Эта проблема в основном связана с модулем расширения WebDAV на сервере IIS. это произошло при использовании действия Опубликовать ИЛИ удалить.

Пожалуйста, попробуйте ниже настройку в веб-конфигурации

<system.webServer>
   <modules>
       <remove name="WebDAVModule" />
   </modules>
   <handlers>
     <remove name="WebDAV" />
   </handlers>
</system.webServer>

3

У меня тоже была такая же проблема, я звоню в WebAPi и получаю эту ошибку. Добавление следующей конфигурации в web.config для служб решило мою проблему

    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/> <!-- add this -->
    </modules>

в файле web.config решил мою проблему. Так я звонил со стороны клиента

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(environment.ServiceUrl);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    HttpResponseMessage response = client.DeleteAsync("api/Producer/" + _nopProducerId).Result;
    if (response.IsSuccessStatusCode)
    {
        string strResult = response.Content.ReadAsAsync<string>().Result;
    }
}

2

Перейдите в файл applicationHost.config (обычно в C: \ Windows \ System32 \ inetsrv \ config) и закомментируйте следующую строку в applicationHost.config

1) Под <handlers>:

<add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" />

2) Также закомментируйте следующий модуль, на который ссылается вышеуказанный обработчик в <modules>

<add name="WebDAVModule" />

Или используйте другой ответ stackoverflow.com/a/47907578/1754743, чтобы УДАЛИТЬ эти обработчики в своем собственном web.config, если вы не хотите (или не можете) изменять файл конфигурации для всей машины
Ekus

2

В моем случае я пропустил добавление {id}в, [Route("")]и получил ту же ошибку. Добавление, которое устранило проблему для меня:[Route("{id}")]


Так много часов потраченного впустую времени, и если бы не ты, я все равно не смог бы решить эту проблему .... Мне интересно, почему он не возвращает 404: @
deadManN

1

У меня был метод ошибки 405, запрещенный, потому что я не сделал общедоступным метод Delete на контроллере WebApi.

Мне потребовалось много времени, чтобы найти это (слишком долго!), Потому что я ожидал в этом случае ошибки Not Found, поэтому я ошибочно предполагал, что мой метод Delete был отклонен.

Причина Not Allowed, а не Not Found в том, что у меня также был метод Get для того же маршрута (что будет нормальным случаем при реализации REST). Общедоступная функция Get соответствует маршрутизации, а затем отклоняется из-за неправильного метода http.

Я знаю простую ошибку, но она может сэкономить время кому-то еще.


1

Просто добавить. Если это ваша конфигурация

config.Routes.MapHttpRoute (
            имя: "DefaultApi",
            routeTemplate: "api / {controller} / {id}",
            по умолчанию: новый {id = RouteParameter.Optional}

пожалуйста, продолжайте делать, как сказал Хьюго, и не устанавливайте атрибут Route для метода get контроллера, это создало проблему в моем случае.


0

У меня была аналогичная проблема, но для PUT - ни одно из других предложений не помогло мне.

Однако я использовал intвместо stringидентификатора по умолчанию . добавление {id:int}к маршруту решило мою проблему.

    [Route("api/Project/{id:int}")]
    public async Task<IHttpActionResult> Put(int id, [FromBody]EditProjectCommand value)
    {
       ...
    }

0

Нам пришлось добавить пользовательские заголовки в наш web.config, поскольку в нашем запросе было несколько заголовков, которые сбивали с толку ответ API.

<httpProtocol>
    <customHeaders>
        <remove name="Access-Control-Allow-Methods" />
        <remove name="Access-Control-Allow-Origin" />
        <remove name="Access-Control-Allow-Headers" />
    </customHeaders>
</httpProtocol>

-1

Атрибут [HttpPost] в верхней части метода Delete решил эту проблему для меня:

[HttpPost]
public void Delete(int Id)
{
  //Delete logic
}

Это может быть причиной того, что это работает на вас. Я использовал более раннюю версию, примерно в начале 2013 года, так что с тех пор было исправлено немало вещей. Однако рад узнать, что это работает на вас.
Крис

4
Честно говоря, это не лучший ответ. Люди, чья проблема была решена с помощью этого метода, используют POST вместо DELETE, поэтому он не может и не должен работать
Александр Дерк

Я считаю, что это связано с тем, что вы используете data(т.е. тело запроса) вместо params(то есть URL-адрес запроса) на стороне клиента.
Thomas Sauvajon

Я согласен с Александром Дерком, это скорее лажа, чем решение.
Basem Sayej
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.