ASP.NET Web API - 405 - czasownik HTTP używany do uzyskania dostępu do tej strony jest niedozwolony - jak ustawić mapowania obsługi


106

Napisałem usługę REST przy użyciu ASP.NET Web API. Próbuję wysłać żądanie HttpDelete, jednak pojawia się następujący błąd:

405 - Czasownik HTTP używany do uzyskania dostępu do tej strony jest niedozwolony

Myślę, że jestem blisko rozwiązania, dowiedziałem się, że powinienem włączyć zdalne zarządzanie IIS, przejść do sekcji Handler Mappings i dodać czasownik DELETE do odpowiedniej pozycji ... ale problem polega na tym, że jest wiele różnych pozycji na lista ... (coś jak tutaj: http://www.somacon.com/p126.php ).

Który powinienem edytować? Niewiele z nich nie ma rozszerzenia, np. "ExtensionUrlHandler-Integrated-4.0" i dodałem do niego czasownik DELETE, ale nadal nie działa ...

To był tylko strzał w ciemno, żeby to zmodyfikować, więc czy powinienem zmodyfikować inną pozycję? Jeśli tak, to jaki? A może jest coś więcej, co powinienem zrobić?

Ta sama usługa internetowa działa doskonale w mojej usłudze lokalnej, więc myślę, że problem dotyczy zdalnych usług IIS ...

Pozdrowienia


3
Hej Bart. Czy możesz zmienić odpowiedź na web.config? To naprawdę lepsze niż odinstalowanie. i masz wielu widzów
Ashkan Sirous

Odpowiedzi:


28

Typową przyczyną tego błędu jest WebDAV . Upewnij się, że go odinstalowałeś.


Wyłączyłem to, ale to nie pomogło
Bart

3
Wyłączenie nie pomaga, musisz go odinstalować.
John_

Mogę potwierdzić, że wyłączenie nie pomaga. @John_ ma rację, musisz odinstalować.
Mike L

7
poniższą odpowiedź giacomellego należy oznaczyć jako poprawną dla tego pytania; jest to rozwiązanie lokalne, które nie wymaga odinstalowywania WebDav.
Joseph Woodward,

1
@ B.ClayShannon WebDAV nie jest samodzielnym programem, jest to funkcja IIS. Tak więc, w zależności od systemu operacyjnego, musisz go znaleźć w funkcjach systemu Windows / rolach / usługach ról / ... cokolwiek innego, co uznają za dobre do sklasyfikowania. Ale jeśli zmiana w pliku web.config nie spowodowała różnic, oznacza to, że i tak napotkasz inny problem.
Frédéric

359

Nie musisz odinstalowywać WebDAV, po prostu dodaj następujące wiersze do pliku web.config:

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

1
To działało dobrze. Trzeba z tego wszystkiego wykorzystać; zawiera obie linie „remove name = ...”.
Chris Patterson

51
Powinna to być akceptowana odpowiedź imho, ponieważ jest to rozwiązanie lokalne, a nie globalne.
Marco Mp

3
to właśnie przyszło mi do głowy przed wielką demonstracją jutro rano. dosłownie uratowałeś mi życie.
Sonic Soul

27
„dosłownie uratowałeś mi życie” - nagle moi klienci nie wydają się tacy źli.
Brandon Gano,

3
Doskonała odpowiedź. Zgadzam się, że to powinna być akceptowana odpowiedź. To sprawiło, że poczułem się znacznie lepiej niż całkowite odinstalowanie WebDAV z naszego serwera internetowego.
mituw16

18

Zmień plik Web.Config jak poniżej

 <system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule" />
</modules>
<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>
</system.webServer>

1
Dodanie usuwania WebDAV i WebDAVMODULE umożliwiło użycie funkcji PUT i DELETE. Dzięki.
Gfw

To hellped kiedy dodać powyższy kod w moim api pliku webconfig projekt
Baqer Naqvi

15

Zmień plik Web.Config jak poniżej. Będzie działać jak urok.

W węźle <system.webServer>dodaj poniższą część kodu

<modules runAllManagedModulesForAllRequests="true">
  <remove name="WebDAVModule"/>
</modules>

Po dodaniu Twój Web.Config będzie wyglądał jak poniżej

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/>
    </modules>
    <httpProtocol>
    <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
    </httpProtocol>
    <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>

Nie powinieneś wracać * do Allow-Origin. Zobacz stackoverflow.com/a/12014554
Karlas,

@Karlas, przeczytaj najpierw pytanie przed umieszczeniem komentarza i oddaniem głosu. Pytanie nie zostało zadane dla „Allow-Origin”, a raczej zostało poproszone o obsługę czasowników http.
Santosh Prasad Sah

3
Nie głosowałem przeciw, tylko komentarz boczny, na wypadek gdyby ktoś kopiował wkleił rozwiązanie.
Karlas

Dzięki! runAllManagedModulesForAllRequests = "true" jest tym, co zrobiło dla mnie.
Eddie Fletcher

8

Miałem ten problem i rozwiązałem:

  1. otwórz IIS
  2. Wybierz witrynę zaplecza

    wprowadź opis obrazu tutaj

  3. w widoku funkcji: otwórz Mapowanie obsługi

wprowadź opis obrazu tutaj

  1. W oknie Handler Mapping znajdź WebDAV

wprowadź opis obrazu tutaj

  1. w Edytuj mapowanie modułów otwórz Ograniczenia żądań

wprowadź opis obrazu tutaj

  1. wprowadź opis obrazu tutaj

Uratował mi życie. Dzięki
deanwilliammills

2
To nie zadziałało. To zepsuło całą witrynę .Net CORE. Musiałem wrócić.
Ravi Ram

4

Jeśli żadne z powyższych rozwiązań nie rozwiązało problemu, tak jak w moim przypadku (nadal utknęło w moim module RestClient w obliczu 405), spróbuj zażądać swojego interfejsu API za pomocą narzędzia takiego jak Postman lub Fiddler. Chodzi mi o to, że problem może być gdzie indziej, jak źle sformatowane żądanie.

Odkryłem, że mój moduł RestClient prosił o 'Put' z nieprawidłowo sformatowanym parametrem Id:

http://myserver/api/someresource?id=75fd954d-d984-4a31-82fc-8132e1644f78

zamiast

http://myserver/api/someresource/75fd954d-d984-4a31-82fc-8132e1644f78

Przypadkowo, źle sformatowane żądanie zwraca 405 - metoda niedozwolona (IIS 7.5)


Mam tutaj taką samą sytuację. Ale w moim przypadku muszę przekazać treść z moją prośbą o PUT. Używam Insomnia (jak Postman) jako klienta narzędzia i działa bardzo dobrze. Ale nie na moim kodzie. Jakieś pomysły?
Darós

3

Niezbyt często, ale może niektórym pomóc.

upewnij się, że używasz [HttpPut] z System.Web.Http

Otrzymywaliśmy komunikat „Metoda niedozwolona” 405 w metodzie dekorowanej HttpPut.

Nasz problem wydaje się być rzadki, ponieważ przypadkowo użyliśmy [HttpPut] atrybutu z System.Web.Mvc, a nie System.Web.Http

Powodem jest to, że resharper zasugerował wersję .Mvc, gdzie - jak zwykle - odwołuje się do System.Web.Http, gdy wyprowadzasz bezpośrednio z ApiController, używaliśmy klasy rozszerzającej ApiController.


1
Jeśli używasz interfejsu API sieci Web, w ogóle nie dekorujesz metod kontrolera - ale używasz czasownika w nazwie metody.
niico

2

Zdarzyło mi się to (metoda 405 niedozwolona), gdy wywoływana przeze mnie metoda webowego interfejsu API miała prymitywne typy parametrów, zamiast typu złożonego, do którego uzyskiwany był dostęp z treści. Tak jak to:

To zadziałało:

 [Route("update"), Authorize, HttpPost]
  public int Update([FromBody] updateObject update)

To nie:

 [Route("update"), Authorize, HttpPost]
 public int Update(string whatever, int whatever, string whatever)

1
Może się to również zdarzyć, jeśli istnieje niezgodność między parametrem w trasie a nazwą zmiennej w sygnaturze metody (innymi słowy: route = "/ api / person / {identity}" i method = "public void putPerson (int id) {...} ”)
RonnBlack

2

Ten błąd pochodzi z modułu obsługi staticfile - który domyślnie nie filtruje żadnych czasowników, ale prawdopodobnie radzi sobie tylko z HEAD i GET.

A to dlatego, że żaden inny przewodnik nie podszedł do talerza i nie powiedział, że poradzi sobie z DELETE.

Ponieważ używasz WEBAPI, które z powodu routingu nie ma plików, a tym samym rozszerzeń, do pliku web.config należy dodać następujące dodatki:

<system.webserver>
    <httpProtocol>
        <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="C:\windows\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="C:\windows\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" />

Oczywiście, co jest potrzebne zależy od trybu klasycznego vs trybu zintegrowanego, a tryb klasyczny zależy od bitowości. Ponadto nagłówek OPTIONS został dodany do przetwarzania CORS, ale jeśli nie wykonujesz CORS, nie potrzebujesz tego.

FYI, Twój plik web.config jest wersją lokalną aplikacji (lub katalogu aplikacji), której najwyższym poziomem jest applicationHost.config.


1

Jeśli jest to IIS 8.0, sprawdź, czy aktywacja HTTP jest włączona. Menedżer serwera -> IIS -> Zarządzaj (patrz prawy u góry) -> Dodaj role i funkcje -> ... -> przejdź do konfiguracji WCF, a następnie wybierz Aktywacja HTTP.


0

W naszym przypadku problem dotyczył logowania federacyjnego między witryną .Net a programem ADFS. Kiedy przekierowanie do ADFS punktem końcowym wctxparametrem potrzebne wszystkie trzy parametry dla WSFederationAuthenticationModule.CreateSignInRequestmetody: rm, id, iru

Podziękowania dla Guillaume Raymond za wskazówkę dotyczącą sprawdzenia parametrów adresu URL!


0

Poza wszystkimi powyższymi rozwiązaniami, sprawdź, czy masz " id" lub jakikolwiek niestandardowy parametr zdefiniowany w DELETEmetodzie jest zgodny z konfiguracją trasy.

public void Delete(int id)
{
    //some code here
}

Jeśli trafisz z powtarzającymi się błędami 405, lepiej zresetuj podpis metody do domyślnej, jak powyżej, i spróbuj.

Konfiguracja trasy domyślnie będzie szukać idw adresie URL. Dlatego nazwa parametru idjest tutaj ważna, chyba że zmienisz konfigurację trasy wApp_Start folderze.

Możesz zmienić typ danych id.

Na przykład poniższa metoda powinna działać dobrze:

public void Delete(string id)
{
    //some code here
}

Uwaga: upewnij się również, że przekazujesz dane przez adres URL, a nie metodę danych, która będzie przenosić ładunek jako treść.

DELETE http://{url}/{action}/{id}

Przykład:

DELETE http://localhost/item/1

Mam nadzieję, że to pomoże.


0

Dodam dla tych, którzy utknęli podczas próby uruchomienia PHP( Laravelw niektórych przypadkach) lub innej unikalnej IISsytuacji hostingu z 405 error, że musisz zmienić verbsw programie obsługi dla tej konkretnej sytuacji ... więc odkąd korzystałem PHP, poszedłem do program PHPobsługi i na karcie Request Restrictions, a następnie Verbsdodaj verbspotrzebne. To było wszystko, co potrzebne, aby dodać do web.configcelu umożliwienia CORSw Laravel.

<handlers>
  <remove name="php-5.6.40" />
  <add name="php-5.6.40" path="*.php" verb="GET,HEAD,POST,PUT,DELETE,OPTIONS" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.6\php-cgi.exe" resourceType="Either" requireAccess="Script" />
</handlers>

0

Żadne z powyższych nie działało dla mnie i miałem problemy z rozwiązywaniem problemów za pomocą strony pomocy technicznej ( https://support.microsoft.com/en-us/help/942051/error-message-when-a-user-visits-a-website -that-is-hosted-on-a-server), a następnie porównałem plik hosta aplikacji z jedną z kopii roboczych i wygląda na to, że brakowało mi kilku programów obsługi, a kiedy dodałem je z powrotem do hosta aplikacji, zaczęło działać. Brakowało mi tego wszystkiego,

<add name="xamlx-ISAPI-4.0_64bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="xamlx-ISAPI-4.0_32bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="xamlx-Integrated-4.0" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="rules-ISAPI-4.0_64bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="rules-ISAPI-4.0_32bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="rules-Integrated-4.0" path="*.rules" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="xoml-ISAPI-4.0_64bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="xoml-ISAPI-4.0_32bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="xoml-Integrated-4.0" path="*.xoml" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="svc-ISAPI-4.0_64bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="svc-ISAPI-4.0_32bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="rules-64-ISAPI-2.0" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" />
<add name="rules-ISAPI-2.0" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" />
<add name="rules-Integrated" path="*.rules" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="xoml-64-ISAPI-2.0" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" />
<add name="xoml-ISAPI-2.0" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" />
<add name="xoml-Integrated" path="*.xoml" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="svc-ISAPI-2.0-64" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" />
<add name="svc-ISAPI-2.0" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" />
<add name="svc-Integrated" path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
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.