136

I wrote REST service using ASP.NET Web API. I'm trying to send HttpDelete request, however I get the following error:

405 - HTTP verb used to access this page is not allowed

I think I'm close to the solution, I found out that I should enable IIS remote management , go to Handler Mappings section and add DELETE verb to the appropriate position... but the problem is that there is a lots of different positions on the list... (sth like here: http://www.somacon.com/p126.php).

Which one should I edit? Few of them don't have extension, e.g. "ExtensionUrlHandler-Integrated-4.0" and I added DELETE verb to it, but it still doesn't work...

It was just a shot in the dark to modify that one, so should I modify different position? If so, which one? Or maybe is there anything more what I should do?

The same web service work perfectly fine on my local service, so I guess the problem is with the remote IIS...

Greetings

Bart
  • 2,301
  • 3
  • 29
  • 27
  • 5
    Hey Bart. Can you change the answer to the web.config one? It is really better than uninstalling it. and you have lots of viewers – Ashkan S Nov 02 '16 at 13:53
  • https://stackoverflow.com/questions/39445717/405-http-verb-used-to-access-this-page-is-not-allowed-iis-8-5-windows-serv/59133377#59133377 – Ali Imran Dec 02 '19 at 05:58

16 Answers16

453

You don't need to uninstall WebDAV, just add these lines to the web.config:

<system.webServer>
  <modules>
    <remove name="WebDAVModule" />
  </modules>
  <handlers>
    <remove name="WebDAV" />
  </handlers>
</system.webServer>
giacomelli
  • 7,287
  • 2
  • 27
  • 31
37

Common cause for this error is WebDAV. Make sure you uninstall it.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I've disabled it, but it didn't help – Bart Mar 25 '12 at 08:27
  • 3
    Disabling doesn't help, you have to un-install it. – John_ May 10 '12 at 16:08
  • I can confirm that disabling doesn't help. @John_ has it right, you have to uninstall. – Mike L Aug 23 '12 at 17:52
  • 9
    giacomelli's answer below should be marked as correct for this question; it's a local solution that doesn't require you to uninstall WebDav. – Joseph Woodward Sep 17 '13 at 10:52
  • HOW do you uninstall it (maybe I don't have it). I've added the code to web.config, which made no diff, and going through Control Panel > Uninstall Programs shows nothing named "webDAV"; is it called something else? – B. Clay Shannon-B. Crow Raven Feb 05 '14 at 00:33
  • 1
    @B.ClayShannon WebDAV is not a standalone program, it is an IIS feature. So, depending on your OS, you have to find it under windows features / roles / roles services / ... whatever else they find good to invent for classifying it. But if the change in web.config made no diff, it means you encounter another issue anyway. – Frédéric Sep 11 '14 at 15:10
  • Best solution for me, I tried web.config changes did not work, then I removed the WebDav feature from server and it now works. – Kbdavis07 Oct 12 '18 at 22:32
25

Change Your Web.Config file as below

 <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>
Hithesh
  • 441
  • 4
  • 9
21

Change Your Web.Config file as below. It will act like charm.

In node <system.webServer> add below portion of code

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

After adding, your Web.Config will look like below

<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>
Santosh Prasad Sah
  • 2,124
  • 1
  • 19
  • 14
10

I had this problem and I solved the following:

  1. open IIS
  2. Select the Backend Site

    enter image description here

  3. in features view: open Handler Mapping

enter image description here

  1. in the Handler Mapping window, Find WebDAV

enter image description here

  1. in Edit Module Mapping, open Request Restrictions

enter image description here

  1. enter image description here
BehrouzMoslem
  • 9,053
  • 3
  • 27
  • 34
7

Check your web.confiq file"

<modules>        
        <remove name="WebDAVModule" />    
    </modules> 
      <handlers>
                <remove name="WebDAV" />
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • Could not use PUT or DELETE on website - IIS 10, AspNetCore 2.2 application, Angular 9 and MVC 3. I edited web.config like the above example (used name="WebDAVHandler" for handler). Decorated MVC methods with [HttpPut} & [HttpDelete], but also had to make MVC Controller methods match the HTTP Verb name, like "PUT" matches to controller method "Put()" - even when using [FromBody]. "DELETE" verb matches to "Delete()" method. Otherwise, got 405 - Method Not Allowed. Also, and finally, had to remove attribute [AutoValidateAntiforgeryToken] from each MVC (api) controller. Login x-xsrf works. – Cwinds Jan 29 '22 at 18:25
4

If none of the above solutions solved your issue like in my case (still stuck with my RestClient module facing 405 ) try to request your Api with a tool like Postman or Fiddler. I mean the problem may be elsewhere like a bad formatted request.

I discover that my RestClient module was asking a 'Put' with an Id paremeter not well formatted :

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

instead of

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

Incidiously, bad formatted request returns 405 - Method Not Allowed (IIS 7.5)

Guillaume Raymond
  • 1,726
  • 1
  • 20
  • 33
  • I have the same situation here. But, in my case, I have to pass a body with my PUT request. I'm using the Insomnia (like Postman) as a tool client and it's works very well. But not on my code. Any ideas? – Darós Jan 04 '19 at 20:47
3

Uncommon but may help some.

ensure you're using [HttpPut] from System.Web.Http

We were getting a 'Method not allowed' 405, on a HttpPut decorrated method.

Our problem would seem to be uncommon, as we accidentally used the [HttpPut] attribute from System.Web.Mvc and not System.Web.Http

The reason being, resharper suggested the .Mvc version, where-as usually System.Web.Http is already referenced when you derive directly from ApiController we were using a class that extended ApiController.

Nick Josevski
  • 4,156
  • 3
  • 43
  • 63
  • 1
    If you're using Web API you don't decorate controller methods at all - but use the verb in the method name. – niico Mar 22 '17 at 12:21
2

I've had this happen (405 method not allowed) when the web api post method I was calling had primitive types for parameters, instead of a complex type that was accessed from the body. Like so:

This worked:

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

This didn't:

 [Route("update"), Authorize, HttpPost]
 public int Update(string whatever, int whatever, string whatever)
Tony
  • 200
  • 2
  • 5
  • 1
    This can also happen if there is a mismatch between the parameter in the route and the variable name in the method signature (In other words route="/api/person/{identity}" and method="public void putPerson(int id){...}") – RonnBlack Dec 16 '15 at 23:00
2

This error is coming from the staticfile handler -- which by default doesn't filter any verbs, but probably can only deal with HEAD and GET.

And this is because no other handler stepped up to the plate and said they could handle DELETE.

Since you are using the WEBAPI, which because of routing doesn't have files and therefore extensions, the following additions need to be added to your web.config file:

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

Obviously what is needed depends on classicmode vs integratedmode, and classicmode depends on bitness. In addition, the OPTIONS header has been added for CORS processing, but if you don't do CORS you don't need that.

FYI, your web.config is the local to the application (or application directory) version whose top level is applicationHost.config.

Gerard ONeill
  • 3,914
  • 39
  • 25
2

If it is IIS 8.0 check if HTTP Activation is enabled. Server manager -> IIS -> Manage (see right top) -> Add Roles and Features -> ... -> get to WCF configuration and then select HTTP Activation.

1

None of the above worked for me and i was trouble shooting using a support page(https://support.microsoft.com/en-us/help/942051/error-message-when-a-user-visits-a-website-that-is-hosted-on-a-server)then i compared the application host file with one of the working copy and seems like i was missing a bunch of handlers and when i added back those into application host its start working. I was missing all these,

<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" />
DanB
  • 2,022
  • 1
  • 12
  • 24
sharon joy
  • 11
  • 1
  • To get those missing handlers registered, you must add `HTTP Activation` in `WCF Services` in `.NET Framework 4.x Features` (Windows Programs and Features, or Windows Server's Roles and Features) I had the exact problem (405 Method not allowed over a .NET SOAP Web service), which requires HTTP Activation feature. – SalvadorGomez Jul 01 '21 at 18:30
0

In our case, the problem was with federated signon between a .Net site and ADFS. When redirecting to the ADFS endpoint the wctx parameter needed all three parameters for the WSFederationAuthenticationModule.CreateSignInRequest method: rm, id, and ru

Thanks to Guillaume Raymond for the tip to check the URL parameters!

Ram
  • 3,092
  • 10
  • 40
  • 56
0

Besides all above solutions, check if you have the "id" or any custom defined parameter in the DELETE method is matching the route config.

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

If you hit with repeated 405 errors better reset the method signature to default as above and try.

The route config by default will look for id in the URL. So the parameter name id is important here unless you change the route config under the App_Start folder.

You may change the data type of the id though.

For example the method below should work just fine:

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

Note: Also ensure that you pass the data over the url not the data method that will carry the payload as body content.

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

Example:

DELETE http://localhost/item/1

Hope it helps.

bfontaine
  • 18,169
  • 13
  • 73
  • 107
Arun
  • 181
  • 1
  • 4
0

I will add for those that get stuck trying to run PHP (Laravel in may case) or other unique IIS hosting situation with the 405 error, that you need to change the verbs in the handler for that for that specific situation... so since I was using PHP I went to the PHP handler and in the Request Restrictions, then Verbs tab, add the verbs you need. This was all I needed to add to the web.config to enable CORS in 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>
Serj Sagan
  • 28,927
  • 17
  • 154
  • 183
0

This may not be applicable to pure "Web API", and probably not for popular public-facing sites, but if you have this error 405 - Method Not Allowed issue on a website with IIS 10, with application built using AspNetCore 2.2, MVC 2 (or 3) and Angular 9, this was my experience. The error msg tells me that I could reach the MVC controller, but that "PUT" was not allowed (or found or listed) as one of my Http verb options on my MVC controller.

I could login with POST (because "Login()" was the name of my MVC controller method decorated with [HttpPost(route)]) and I could use the GET verb successfully. I use Routes for navigation.

But I could not use POST to create a new entry, PUT to edit them or DELETE to remove them. I received the "405" error.

In my case, removing the WebDAV references from web.config only changed the error I was receiving from a "405" to "400 - Bad Request".

But, this info was helpful, too, so I went back to Development mode, changed my MVC Controller methods names to match the HTTP Verb names, like "PUT" now matches to controller method "Put()" - even using [FromBody]. "DELETE" verb now matches to "Delete()" method name and POST matches to "Post()". I did not remove or change any necessary parameters like "id", etc, from the new method name.

I began testing again and received errors in dotnet server compile showing a problem with cross-site antiforgery issues in MVC Controllers paths.

I am also using antiforgery header/cookies in StartUp.cs, and it works in login POST, so I did not change anything in StartUp.cs.

But my MVC controller classes were decorated with the [AutoValidateAntiforgeryToken] attribute (don't fully understand why I used it, just followed my example), and my MVC controller methods were decorated with [HttpPut], etc.

So, because of the dotnet compile error, I removed the class-level attribute [AutoValidateAntiforgeryToken], but left the [HttpPut], etc, attributes in place at method-level for each MVC controller.

This was my solution, edited the web.config to remove WebDAV, made controller method names match http verbs and removed [AutoValidateAntiforgeryToken] attribute from MVC controller classes - since my website is private, not public facing.

I still have the Login header x-xsrf-token / cookies / antiforgery stuff in my StartUp.cs, and it still works on login. Still investigating how to get it to work at the MVC controller class level however.

But, for now, I can POST, PUT and DELETE with no error.

Update - from reading a few other posts about the **400 - Bad Request" issue, I found this link to "ASP.NET Core Web Api Antiforgery". It was very helpful. After doing the updates that the article suggested which included adding an MVC AntiForgeryController and an Angular Injectable service, I am able to PUT, POST and DELETE with CRSF turned on for my Controllers, using "ValidateAntiForgeryToken" on most controllers, but "Ignoring" some methods(), like the article suggests.

Besides the changes in the article, I also had this app registration in my StartUp.cs in the Configure() method - I have no public-facing routes except "login":

        app.Use(nextDelegate => context =>
        {
            string path = context.Request.Path.Value;
            string[] directUrls = { "/<first restricted url route>", "/<second restricted url route>", "/<third>" };
            if (path.StartsWith("/api") || string.Equals("/", path) ||
                directUrls.Any(url => path.StartsWith(url)))
            {
                var tokens = antiforgery.GetAndStoreTokens(context);
                context.Response.Cookies.Append("XSRF-REQUEST-TOKEN", tokens.RequestToken,
                    new CookieOptions()
                    {
                        HttpOnly = false,
                        Secure = false,
                        IsEssential = true
                    });
            }
            return nextDelegate(context);
        });
Cwinds
  • 167
  • 11