WebAPI Delete nie działa - metoda 405 niedozwolona

120

Doceniam każdą pomoc w tej sprawie, ponieważ strona ma zostać uruchomiona dziś wieczorem!

Mam kontroler interfejsu API sieci Web z metodą usuwania. Metoda działa dobrze na moim komputerze lokalnym z uruchomionym IIS Express (Windows 8), ale gdy tylko wdrożyłem ją na aktywnym serwerze IIS (Windows Server 2008 R2), przestała działać i wyświetla następujący komunikat o błędzie:

Błąd HTTP 405.0 - metoda niedozwolona Strona, której szukasz, nie może zostać wyświetlona, ​​ponieważ używana jest nieprawidłowa metoda (zlecenie HTTP)

Rozejrzałem się po sieci w poszukiwaniu rozwiązań i wdrożyłem najbardziej rozsądne. Moja konfiguracja internetowa ma następujące ustawienia:

<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>

Próbowałem również zmienić mapowania obsługi i filtrowanie żądań w usługach IIS bezskutecznie. Należy pamiętać, że wydaje się, że reguły tworzenia WebDAV w usługach IIS są wyłączone.

Wszelkie pomysły będą mile widziane. Dzięki.

Chris
źródło

Odpowiedzi:

199

W końcu znalazłem rozwiązanie! Jeśli napotkasz ten sam problem, dodaj następujące elementy do pliku web.config

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

mam nadzieję, że to pomoże

Chris
źródło
2
Musiałem również dodać usunięcie w sekcji obsługi zgodnie ze stackoverflow.com/a/6698096/254156
rrrr
3
Tu też pracował. Ale czy ktoś może mi wyjaśnić związek z WebDAVModule?
Boas Enkler
11
dla tych, którzy po prostu kopiują i wklejają: runAllManagedModulesForAllRequests = "true" nie jest tak naprawdę potrzebne i mogą faktycznie zepsuć inne rzeczy.
Zar Shardan,
Niektóre inne posty internetowe sugerują usunięcie modułu za pomocą sekcji Moduły IIS, to go wyłącza, ale nadal powoduje ten / podobny problem, jest to najbardziej niezawodna metoda
Anthony Main
4
@ZarShardan (i inni) FYI: Jeśli usuniesz atrybut runAllManagedModulesForAllRequests = "true", będziesz musiał również dodać <remove name = "WebDAV" /> w węźle <handlers>.
Aaron
65

W niektórych przypadkach usunięcie go tylko z modułów może spowodować następny błąd:

500.21 Program obsługi „WebDAV” ma uszkodzony moduł „WebDAVModule” na liście modułów

Moduł: IIS Web Core Notification: ExecuteRequestHandler "

zaproponowano tutaj rozwiązanie . Należy również usunąć go z obsługi.

<system.webServer>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
    <handlers>
        <remove name="WebDAV" />
    </handlers>
</system.webServer>
aleha
źródło
1
to działa dla mnie, ale czy ktoś może rzucić trochę światła na to, czym właściwie jest WebDAV?
Nazrul Muhaimin
31

W moim przypadku żadne z powyższych rozwiązań nie działało. To dlatego, że zmieniłem nazwę parametru w mojej Deletemetodzie.

miałem

public void Delete(string Questionid)

zamiast

public void Delete(string id)

Muszę użyć tej idnazwy, ponieważ jest to nazwa zadeklarowana w moim WebApiConfigpliku. Zwróć uwagę na idnazwę w trzecim i czwartym wierszu:

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

Mam to rozwiązanie stąd .

Hugo Nava Kopp
źródło
15

DELETECzasownik JavaScript dla HTTP musi wyglądać następująco:

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

Czy nie używać coś takiego:

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

tak jak podczas korzystania z POSTmetody.

Pavel Kharibin
źródło
1
Cześć @Pavel, to jest poprawne, jeśli rzeczywiście używasz implementacji w pełni RESTful. Niestety nie wszyscy to robią i dość często zdarza się, że programiści używają POST zamiast DELETE itp. Dziękuję za wyjaśnienie.
Chris
5

Po wypróbowaniu prawie wszystkich rozwiązań tutaj zadziałało. Dodaj to do pliku konfiguracyjnego interfejsów 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>
Nithin Chandran
źródło
Próbowałem wielu rzeczy, to działało. .NET w wersji 4.6.1 - dzięki.
Ketan
4

Jeśli używasz usług IIS 7.0 lub nowszej wersji. Ten problem dotyczy głównie modułu rozszerzenia WebDAV na serwerze IIS. stało się to podczas korzystania z akcji Opublikuj LUB usuń.

Spróbuj poniższych ustawień w konfiguracji sieciowej

<system.webServer>
   <modules>
       <remove name="WebDAVModule" />
   </modules>
   <handlers>
     <remove name="WebDAV" />
   </handlers>
</system.webServer>
Abhishek B.
źródło
3

Miałem też ten sam problem, dzwonię do WebAPi i otrzymuję ten błąd. Dodanie następującej konfiguracji w web.config dla usług rozwiązało mój problem

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

w pliku web.config rozwiązało mój problem. Oto jak dzwoniłem po stronie klienta

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;
    }
}
Aamir
źródło
2

Przejdź do pliku applicationHost.config (zwykle w C: \ Windows \ System32 \ inetsrv \ config) i zakomentuj następujący wiersz w pliku applicationHost.config

1) Pod <handlers>:

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

2) Skomentuj również następujący moduł, do którego odwołuje się powyższy program obsługi w ramach <modules>

<add name="WebDAVModule" />
arviman
źródło
Lub użyj innej odpowiedzi stackoverflow.com/a/47907578/1754743, aby USUNĄĆ te programy obsługi w swoim własnym web.config, jeśli nie chcesz (lub nie możesz) modyfikować pliku konfiguracyjnego dla całego komputera
Ekus
2

W moim przypadku przegapiłem dodanie {id}do [Route("")]i otrzymałem ten sam błąd. Dodanie tego rozwiązało problem:[Route("{id}")]

Reza
źródło
Tyle godzin zmarnowanego czasu, a gdyby nie ty, nadal nie mógłbym tego rozwiązać ... Zastanawiam się, dlaczego nie zwraca 404: @
deadManN
1

Wystąpił błąd 405 Metoda niedozwolona, ​​ponieważ pominąłem publiczne udostępnienie metody Delete na kontrolerze WebApi.

Znalezienie tego zajęło mi dużo czasu (zbyt długo!), Ponieważ spodziewałbym się w tym przypadku błędu Nie znaleziono, więc błędnie założyłem, że moja metoda Delete została odrzucona.

Powodem niedozwolonego zamiast nie znalezionego jest to, że miałem również metodę Get dla tej samej trasy (co będzie normalnym przypadkiem podczas implementowania REST). Publiczna funkcja Get jest dopasowywana przez routing, a następnie odrzucana z powodu niewłaściwej metody http.

Prosty błąd, który znam, ale może zaoszczędzić trochę czasu komuś innemu.

Paul D.
źródło
1

Wystarczy dodać. Jeśli to jest twoja konfiguracja

config.Routes.MapHttpRoute (
            name: "DefaultApi",
            routeTemplate: "api / {kontroler} / {id}",
            wartości domyślne: nowy {id = RouteParameter.Optional}

proszę, rób dalej tak, jak powiedział Hugo i nie ustawiaj atrybutu Route na metodę get kontrolera, to spowodowało problem w moim przypadku.

user6247020
źródło
0

Miałem podobny problem, ale dla PUT - żadna z innych sugestii nie zadziałała.

Jednak używałem intzamiast domyślnego stringidentyfikatora. dodanie {id:int}do trasy rozwiązało mój problem.

    [Route("api/Project/{id:int}")]
    public async Task<IHttpActionResult> Put(int id, [FromBody]EditProjectCommand value)
    {
       ...
    }
Hath
źródło
0

Musieliśmy dodać niestandardowe nagłówki do naszego pliku web.config, ponieważ nasze żądanie zawierało wiele nagłówków, które myliły odpowiedź interfejsu API.

<httpProtocol>
    <customHeaders>
        <remove name="Access-Control-Allow-Methods" />
        <remove name="Access-Control-Allow-Origin" />
        <remove name="Access-Control-Allow-Headers" />
    </customHeaders>
</httpProtocol>
Sadok
źródło
-1

Atrybut [HttpPost] w górnej części metody Delete rozwiązał ten problem:

[HttpPost]
public void Delete(int Id)
{
  //Delete logic
}
Andriy Gubal
źródło
To może być powód, dla którego to działa dla Ciebie. Byłem na wcześniejszej wersji, około początku 2013 roku, więc sporo rzeczy zostało naprawionych. Cieszę się, że to działa dla Ciebie.
Chris
4
Szczerze mówiąc, to nie jest dobra odpowiedź. Ludzie, których problem został rozwiązany za pomocą tego używasz POST zamiast DELETE więc nie mógł i nie powinien prace
Alexander Derck
Uważam, że dzieje się tak dlatego, że używasz data(tj. Treści żądania) zamiast params(tj. Adresu URL żądania) po stronie klienta.
Thomas Sauvajon
Zgadzam się z Alexandrem Derckiem, jest to raczej kludge niż rozwiązanie.
Basem Sayej