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.

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


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>

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 .


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.


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>

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>

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

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

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}")]


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.


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.


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)
    {
       ...
    }

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>

-1

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

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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.