Видалення WebAPI не працює - метод 405 не дозволено


120

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

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

Помилка HTTP 405.0 - метод не дозволений. Шукану сторінку не можна відобразити, оскільки використовується недійсний метод (HTTP Verb)

Я роздивився Інтернет, щоб знайти рішення, і реалізував більшість розумних. Моя веб-конфігурація має такі налаштування:

<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 (та інші) FYI: Якщо ви видалите атрибут runAllManagedModulesForAllRequests = "true", вам також потрібно буде додати <delete 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) У розділі <Обробники>:

<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, оскільки я пропустив зробити метод Видалення на контролері WebApi загальнодоступним.

Мені знадобилося багато часу, щоб знайти це (занадто довго!), Тому що я б очікував помилки Not Found в цьому випадку, тому я неправильно припускав, що моєму методу Delete було відмовлено.

Причина "Не дозволено", а не "Не знайдено" полягає в тому, що у мене також був метод Get для того ж маршруту (що буде нормальним випадком при впровадженні REST). Функція public get узгоджується маршрутизацією, а потім відмовляється через неправильний метод http.

Я знаю просту помилку, але це може врятувати когось іншого деякий час.


1

Просто додати. Якщо це ваша конфігурація

config.Routes.MapHttpRoute (
            назва: "DefaultApi",
            routeTemplate: "api / {контролер} / {id}",
            за замовчуванням: новий {id = RouteParameter.O optional)

будь ласка, продовжуйте робити так, як сказав Юго, і не встановлюйте атрибут Route методу get Controller, це створило проблему в моєму випадку.


0

У мене була схожа проблема, але щодо PUT - жодна з інших пропозицій не працювала для мене.

Однак я використовував, intа не за замовчуванням stringдля id. додавання {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, тому він не міг і не повинен працювати
Alexander Derck

Я вважаю, це тому, що ви використовуєте data(тобто тіло запиту) замість params(тобто URL запиту) на стороні клієнта.
Thomas Sauvajon

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