OData $batch endpoint not found when hosted in IIS - iis-7.5

I'm struggling to figure this out - I have an OData V4 service which I have developed using .Net ODataConventionModelBuilder. Everything works fine when running "within visual studio" (i.e. localhost:port/service) but when I publish the service to IIS I can no longer make batch requests.
Example1 : Running under IISExpress while visual studio is running
GET http://localhost:1234/service/SomeResource
- works fine to access a resource and return JSON response
POST http://localhost:1234/service/$batch
- works fine to send a batch request (obviously with body data) for multiple GETs
Example2 : Hosting under IIS
GET http://localhost/service/SomeResource
- works fine to access a resource and return JSON response
POST http://localhost/service/$batch
- fails with a HTTP 404 Not Found
"Message": "No HTTP resource was found that matches the request URI 'http://localhost/service/$batch'.",
"MessageDetail": "No route providing a controller name was found to match request URI 'http://localhost/service/$batch'"
so I'm stuck I dont understand why routing is working ok when running under studio/IISExpress and not under proper IIS.

Ok seems this was down to a problem interpreting the url because of the $batch part.
Adding this to web.config solved it ok.
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>

Related

Adding <customHeaders> in webconfig causes 500 error in sub applications in IIS?

My web site is written by ASP.NET MVC 4 and hosted on IIS 6.2.
I need to add custom headers(X-Frame-Options,X-XSS-Protection etc.) to web config in main application.
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
<add name="X-XSS-Protection" value="1" />
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
After I did it, my sub apllications getting http 500 error.I have no idea why this happening.
I already tried option.Also tried remove every customheaders from response headers in IIS, also tried add manually in response headers.
Can you give me an advice to fix this issue?
Try adding the header at the Server level by using "HTTP Response Header" applet.
I think you are adding headers in the "Default Web Site" now. Default Site the header starting with "X-" will give error. I had faced this issue.
You can also try adding it in each App or virtual directory under "Default Web Site".

HTTP Error 405.0 - Method Not Allowed in IIS Express

When issuing a perfectly cromulent verb to a local IIS Express web-site under Visual Studio 2013:
CROMULENT http://localhost:7579/Handler.ashx HTTP/1.1
Host: localhost:7579
the server responds with the error:
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS, TRACE
That is a request to a "generic handler" (i.e. .ashx). If if i try again to a static resource:
SCHWIFTY http://localhost:7579/Default.htm HTTP/1.1
Host: localhost:7579
the server responds with the error:
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS, TRACE
This is all by way to trying to use HTTP verbs:
DELETE http://localhost:7579/Handler.ashx HTTP/1.1
Host: localhost:7579
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS, TRACE
PUThttp://localhost:7579/Handler.ashx HTTP/1.1
Host: localhost:7579
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS, TRACE
This question has been asked to death, sometimes by me. But nobody has ever come up with a solution.
</Question>
Microsoft's Bug
The problem, fundamentally, is that Microsoft ships IIS and IISExpress broken by default. Rather than handling HTTP verbs, as a web-server is required to do, they don't handle verbs.
This can most easily be seen when managing full IIS running on Windows Server. Pick any of the built-in handlers (e.g. the cshtml handler), and you can see that someone thought it would be hilarious if it only worked with GET, HEAD, POST, and DEBUG verbs:
rather than correctly implementing support for HTTP in an HTTP server.
The question becomes:
why exactly doesn't it work
how exactly to fix it
how to fix it in IIS Express (without any management tools)
why it continues to be shipped, year after year, broken
Question 1. Why doesn't it work?
The first question is why doesn't it work. Let's look at an IIS server where we've removed every handler except the basic Static file handler:
The handler is configured to all all verbs:
The only handler left is set to allow any verb. Yet if we issue a request to the web server we get the error:
DELETE http://scratch.avatopia.com/ HTTP/1.1
Host: scratch.avatopia.com
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS, TRACE
Server: Microsoft-IIS/7.5
Why is this happening?
Why didn't it work? Where is the configuration option that says:
GET
HEAD
OPTIONS
TRACE
because the server itself is saying those are the only supported verbs.
Yet if we change it to a GET it works fine:
GET http://scratch.avatopia.com/ HTTP/1.1
User-Agent: Fiddler
Host: scratch.avatopia.com
HTTP/1.1 200 OK
Content-Type: text/html
Question 2. How to fix it?
The common wisdom is to remove WebDAV. Nobody knows what WebDAV is, how it could be a problem, why it is a problem, or why it exists if it only causes problems. WebDAV can be removed as a handler from the IIS administration user interface:
which is identical to adding a remove entry from the handlers section in web.config (the UI itself adds the entry to web.config for you):
<system.webServer>
<handlers>
<remove name="WebDAV" />
</handlers>
</system.webServer>
Except this doesn't work. So how do we fix it?
Starting with IIS it seems that WebDAV has become even more of a virus. Rather than simply disabling it as a handler, you have to completely install or remove it as a module:
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
</system.webServer>
That sounds like a reason idea, except in my test case, on IIS 7.5, WebDAV is both not installed, and removed as a module:
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS, TRACE
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Tue, 10 May 2016 19:19:42 GMT
Content-Length: 0
So, if we can figure out how to solve the problem, we can answer question number two.
Question 3. How to fix it in IIS Express
Starting with Visual Studio 20131, Visual Studio no longer uses a mini web-server called Cassini. It uses a portable install of IIS Express itself (i.e. IIS Express Windows feature doesn't need to be installed).
Most of the above fix (attempts) (fail) in IIS. But nobody has dealt with them in IIS Express of Visual Studio 2013 (which is how this question is different from any others).
Question 4. Why does this keep happening?
It's been over 15 years, and this still keeps happening. There must be a good reason why IIS does not function as a web-server. But what is it? I've not been able to find any knowledge base article, or blog post, explaining why the IIS team refuses to function correctly.
Bonus Reading
The most popular Stackoverflow question for this problem: ASP.NET Web API - PUT & DELETE Verbs Not Allowed - IIS 8
Research Effort
HTTP Error 405.0 - Method Not Allowed, with POST (no answer, php)
HTTP Error 405.0 - Method Not Allowed (no answer)
POST verb not allowed (php)
HTTP Error 405.0 - Method Not Allowed in ASP.net MVC5 (no answer, mvc)
JQuery File Uploader = error 405 IIS8.5 (jquery no answer)
IIS 7.5 405 Method Not Allowed for PUT from StaticFileModule (no answer, static module, iis)
The HTTP verb POST used to access path is not allowed ("don't use verbs")
http error 405 method not allowed error with web.API (uninstall WebDAV; already isn't)
Handling Perl IIS 7.5 (perl)
HTTP Error 405.0 - Method Not Allowed using Jquery ajax get (ajax)
What causes an HTTP 405 "invalid method (HTTP verb)" error when POSTing a form to PHP on IIS? (iis6, ftp, php)
http://forums.asp.net/t/1648594.aspx ("have you tried pinging your computer")
Angular $resource POST/PUT to WebAPI 405 Method Not Allowed (try removing WebDAV handlder and WebDAV module)
Http Error 405.0 - method not allowed iis 7.5 module staticfilemodule (no solution)
Unable to set up WebDAV with IIS 7 *(trying to setup webdav)*
Android SOAP request is returning HTTP Response 405 (no solution)
wcf service doesn't allow POST (wcf)
WebAPI Delete not working - 405 Method Not Allowed (WebAPI; remove WebDAV)
I seem to pick up on a bit of frustration in the question, so the actual question is a bit unclear. What specifically is it that you are trying, but failing, to do? What do you expect of the answer?
Anyway, based on this comment in the question:
This is all by way to trying to use HTTP verbs:
and the corresponding samples involving a generic handler, I'll take a stab at showing what is needed to make it possible to PUT and DELETE a generic handler.
In order to allow PUT and DELETE on a generic handler, you must allow it in the web.config of the application. To do that you should register a handler for *.ashx as follows:
<system.webServer>
<handlers>
<add name="SimpleHandlerFactory-Integrated-WithPutDelete"
path="*.ashx"
verb="GET,HEAD,POST,DEBUG,PUT,DELETE"
type="System.Web.UI.SimpleHandlerFactory"
resourceType="Unspecified"
requireAccess="Script"
preCondition="integratedMode" />
</handlers>
</system.webServer>
Depending on how you originally set up the web site/application, there may or may not be a handler registered for type="System.Web.UI.SimpleHandlerFactory" in your web.config file. If there is one, you should be able to just modify that entry and add the verbs you want to allow.
You'll note that this entry has the preCondition="integratedMode". This should, I believe, work when debugging in Visual Studio using IIS Express. In a real IIS deployment, the handler registration may need to be modified to match the application pool that will run the application. For an application running in classic mode (not integrated), it would look something like this (not tested so may be wrong):
<system.webServer>
<handlers>
<add name="SimpleHandlerFactory-ISAPI-4.0_64bit-WithPutDelete"
path="*.ashx"
verb="GET,HEAD,POST,DEBUG,PUT,DELETE"
modules="IsapiModule"
scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv4.0,bitness64"
responseBufferLimit="0" />
</handlers>
</system.webServer>
The exact details would depend on the framework version an bit-ness of the application pool.
If you are debugging in Visual Studio using IIS Express, you should have a look at the applicationhost.config which sets up a lot of the defaults regarding IIS Express. It is located in:
My Documents\IISExpress\config
The untested handler registration above for a classic pipeline application pool is a slight modification of a handler registration in that file. There are in my environment 6 separate entries for *.ashx, with varying preconditions, in that file.
It might be a good idea to explicitly remove all of these in your web.config if you want to have your own registration which allows PUT and DELETE. Not all of them would actually be active/registered at the same time since the preconditions are (I suppose) mutually exclusive, but at least for me it works to just remove them all, one after the other. In my environment the section with the removes looks like this:
<remove name="SimpleHandlerFactory-ISAPI-4.0_64bit"/>
<remove name="SimpleHandlerFactory-ISAPI-4.0_32bit"/>
<remove name="SimpleHandlerFactory-Integrated-4.0"/>
<remove name="SimpleHandlerFactory-Integrated"/>
<remove name="SimpleHandlerFactory-ISAPI-2.0"/>
<remove name="SimpleHandlerFactory-ISAPI-2.0-64"/>
Hope this shines at least a bit of light into dark places!
okay so i ran into this same exact problem on IIS 7.5 when trying to PUT or DELETE it returned a 405.
i was specifically trying to setup a MEAN stack with IISnode module. when accessing the static HTML file IIS was serving up i was able to GET and PUSH but not PUT or DELETE.
-- the problem --
i believe that the issue is with IIS server itself. take a look at this post here:
https://blogs.msdn.microsoft.com/saurabh_singh/2010/12/10/anonymous-put-in-webdav-on-iis-7-deprecated/
https://support.microsoft.com/en-us/kb/2021641
it appears that IIS no longer allows Anonymous PUT or DELETE
so in the end i just went with a nodejs webserver instead
-- however --
i have not tried this but perhaps you might want to look into modifying the IIS system config file itself called the ApplicationHost.config located here:
C:\Windows\System32\inetsrv\config
make sure to use notepad with administrator privileges
let me know how it goes and i might try and do this later when i have time
There is a lot of talk about removing WebDAV and that will fix the problem - but if you're wondering what WebDAV is and what its used for, check out this page:
https://www.cloudwards.net/what-is-webdav/
Holy Damn, many research these 2 days....
No WebDav installed, no typical handler modifications (SimpleHandlerFactory, ExtensionlessUrl)
For those using any PHP Frameworks just as: Laravel, CakePHP etc
I couldn't make IIS Failed Tracing Logs work, so...
All I did was, modify PHP handler [MODIFY: php-X_VERSION]:
<handlers>
<remove name="php-X_VERSION" />
<add name="php-X_VERSION" path="*.php" verb="GET,HEAD,POST,PUT,DELETE" modules="FastCgiModule" scriptProcessor="D:\Program Files\PHP\X_VERSION\php-cgi.exe" resourceType="Either" requireAccess="Script" />
</handlers>
I have no WebDAV installed, and am running IIS Express from VS2019. After some digging, I came upon the applicationhost.config file used by IIS Express, and ended up with a solution by changing my own project web.config file. In the system.webServer/handlers section, add the following:
<system.webServer>
<handlers>
<remove name="PageHandlerFactory-ISAPI-4.0_64bit"/>
<remove name="PageHandlerFactory-ISAPI-4.0_32bit"/>
<remove name="PageHandlerFactory-Integrated-4.0"/>
<remove name="PageHandlerFactory-Integrated"/>
<remove name="PageHandlerFactory-ISAPI-2.0"/>
<remove name="PageHandlerFactory-ISAPI-2.0-64"/>
<add name="PageHandlerFactory-ISAPI-4.0_64bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG,PUT" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="PageHandlerFactory-ISAPI-4.0_32bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG,PUT" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="PageHandlerFactory-Integrated-4.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG,PUT" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="PageHandlerFactory-Integrated" path="*.aspx" verb="GET,HEAD,POST,DEBUG,PUT" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="PageHandlerFactory-ISAPI-2.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG,PUT" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
<add name="PageHandlerFactory-ISAPI-2.0-64" path="*.aspx" verb="GET,HEAD,POST,DEBUG,PUT" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
</handlers>
</system.webServer>
All this does, is it adds the word "PUT" to the verb attribute of each handler.
I also have to add that I am working on an older project and created the API endpoints with *.aspx files, which is why other solutions found googling did not work. So if you are using VS2019 and get the error 405.0 - Method not Allowed and you already removed WebDAV and expose your API with .aspx files this might work.

CORS problems in WebAPI hosted in IIS

I'm trying to implement an application that uses the same Token Based Authentication mechanism demonstrated in this really awesome example by Taiseer Joudeh.
In my application I kept encountering Cors problems. In some configurations I would get a 500 error on the Preflight (OPTIONS) request for the POST to get the token or I could get the token but then get a 404 error on the preflight request for the GET request to the actual API call with the Bearer token.
One difference was that Taiseer's code was setup to host in IISExpress (or Azure) and mine is hosted on Local IIS (running on Windows 7 at the moment).
On a hunch I tried hosting his API under Local IIS and I found the exact same problem. (500 error on the preflight request for the token and it looks like the actual API will work properly)
From what I've been reading it seems like this may be some conflict between the modules and handlers in IIS and the Cors implementation in WebApi but Taiseer's implementation works when hosted in Azure so perhaps it is a difference in the version of IIS (I'm currently running under Windows 7).
How can I sort out what is causing the problem?
The root of the problem
The Token action is not hosted in a controller but is instead built in somewhere in the lower level plumbing. The only access to the mechanism is through the override method GrantResourceOwnerCredentials() in the class that extends OAuthAuthorizationServerProvider. (In our case is ApplicationOAuthProvider.cs).
GrantResourceOwnerCredentials() does have the context available but it is not called as part of the PreFlight request so you have no way to insert the appropriate PreFlight response headers for CORS.
The solution
We eventually settled on the following solution. I'm not a big fan of it because it forces these headers into every response but at least it works.
The solution was to override Application_PreSendRequestHeaders() method in Global.asax to insert the appropriate headers.
Global.asax.cs
void Application_PreSendRequestHeaders(Object sender, EventArgs e)
{
var origin = Request.Headers.Get("Origin");
var validOrigins = ConfigurationManager.AppSettings["allowedCorsOrigins"].Split(',');
if(validOrigins.Any(o => o == origin))
{
Response.Headers.Set("Access-Control-Allow-Origin", origin);
Response.Headers.Set("Access-Control-Allow-Credentials", "true");
Response.Headers.Set("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, withcredentials, Prefer");
Response.Headers.Set("Access-Control-Expose-Headers", "Claims, *");
Response.Headers.Set("Access-Control-Max-Age", "600");
Response.Headers.Set("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
}
}
This requires the following web.config entries:
web.config
<configuration>
<appSettings>
<add key="allowedCorsOrigins" value="http://www.allowedsite1.net,http://localhost:22687" />
<add key="allowedCorsMethods" value="get, post, put, delete, options, batch" />
<add key="allowedCorsHeaders" value="*" />
</appSettings>
...
</configuration>
The reason for the loop to search for the valid origins is that you can't respond with a list of allowed origins...
This solved most of the problems with one exception (If I recall correctly was problems with PUT and DELETE verbs). This required removing the "ExtensionlessUrlHandler-Integrated-4.0" and re-adding it with a path and verb in the handlers section of the web.config.
web.config (2nd change)
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="" />
</handlers>
....
</system.webServer>
Useful links related CORS
Really good description of PreFlight for CORS
Excellent Sample Application using Token Auth
It is not the IdentityServer you are using but it could be the same problem. Regarding to the IdentityServer´s Github page you have to activate RAMMFAR (runAllManagedModulesForAllRequests) for your application when running under the IIS.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
</modules>
</system.webServer>
I had this same issue, I did everythin as suggested by Mr. Tom hall. But still chrome reported no Access-control-allow-origin header is present.. after inspecting with fidler i realized that my request goes through a proxy server and my proxy server is handling the preflight options request..
So in "internet options" i removed the proxy server and found out that everything is working...!!!

ASP.NET Web API returns 404 for PUT only on some servers

I have written a site that uses ASP.NET MVC Web API and everything is working nicely until I put it on the staging server. The site works fine on my local machine and on the dev web server. Both dev and staging servers are Windows Server 2008 R2.
The problem is this: basically the site works, but there are some API calls that use the HTTP PUT method. These fail on staging returning a 404, but work fine elsewhere.
The first problem that I came across and fixed was in Request Filtering. But still getting the 404.
I have turned on tracing in IIS and get the following problem.
168. -MODULE_SET_RESPONSE_ERROR_STATUS
ModuleName IIS Web Core
Notification 16
HttpStatus 404
HttpReason Not Found
HttpSubStatus 0
ErrorCode 2147942402
ConfigExceptionInfo
Notification MAP_REQUEST_HANDLER
ErrorCode The system cannot find the file specified. (0x80070002)
The configs are the same on dev and staging, matter of fact the whole site is a direct copy.
Why would the GETs and POSTs work, but not the PUTs?
For those of you who do not have WebDAV enabled but are still running into this issue using MVC 4's Web API's...
Steve Michelotti documented a solution that worked for me here.
At the end of the day, I enabled all verbs (verb="*") to the ExtensionlessUrlHandler-Integrated-4.0 handler in my web config.
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Those IIS servers have web-dav module installed on them and i bet it is not needed and it was installed because the person installing ticked all boxes.
Just remove web-dav from iis.
Alternatively use web.config to remove web dav module:
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
...
It seems there are a number of reasons that this occurs. None of the above quite worked for me. I already had the ExtensionlessUrlHandler settings in web.config with all the required HTTP verbs. In the end I had to make the following changes in IIS:
In IIS select your website and double-click Handler Mappings
Find ExtensionlessUrlHandler-ISAPI-4.0_32bit and double-click
In the dialog that appears, click Request Restrictions
On the Verbs tab add the missing HTTP verbs separated by commas (in my case it was PUT and DELETE
Click Ok where required and answer Yes in the Edit Script Map dialog that pops up.
Repeat for ExtensionlessUrlHandler-ISAPI-4.0_64bit
Hope this helps somebody :)
My hosting provider could NOT uninstall WebDAV as this would affect everyone.
This, runAllManagedModulesForAllRequests="true" , worked but was not recommended.
Many fixes included removing the module for WebDAVModule but that still didn't work. I removed the handler also, and finally I could use all verbs POST GET PUT DELETE.
Remove WebDAVModule and WebDAV in modules and handlers.
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
I fixed this removing the UrlScan ISAPI filter
In my case, none of these solutions applied.
I fixed it by changing my app pool to Integrated instead of Classic.
The handler:
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
is not going to work with a Classic app pool, since its preCondition is integratedMode.
Rick Strahl from West-Wind recommended the following:
< handlers>
< remove name="ExtensionlessUrlHandler-Integrated-4.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>
Which Worked very well for me.
Hi For me none of the solutions worked. I finally got it working doing this :
1) In IIS select you application.
2) Go to Request Filtering
3) Then select the HTTP Verbs tab
4) I found the PUT and other verbs to have allowed to false but wasn't able to just edit so I removed the verb then either in the pane on the right select allow verb or right click on the list and select it. Enter the verb you're having troubles with and voilĂ  !
Hope this will help someone !
I resolved this by changing my application pool for the website to Integrated mode when it was previously on Classic mode.

"405 method not allowed" in IIS7.5 for "PUT" method

I use WebClient type to upload *.cab files to my server. On the server side, I registered a HTTP handler for *.cab file with the PUT method as below:
<add name="ResultHandler" path="*.cab" verb="PUT" type="FileUploadApplication.ResultHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode" />
But I always get a "405 method not allowed" error. The response said the allowed methods are as below:
Headers = {Allow: GET, HEAD, OPTIONS, TRACE
Content-Length: 1293
Content-Type: text/html
Date: Fri, 27 May 2011 02:08:18 GMT
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET}
Even if I explicitly allow the PUT method in the IIS Request Filtering for my web application, the same error still occurs.
I suspect this is a IIS related issue. I'm hoping someone could shed some light on this for me.
Often this error is caused by the WebDAV module that try to handle this kind of requests. An easy solution is to remove it from modules and from handlers of the system.webServer section just inside your web.config file.
Here a configuration example:
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
</system.webServer>
I enabled the Failed Request Tracing, and got the following info:
<EventData>
<Data Name="ContextId">{00000000-0000-0000-0F00-0080000000FA}</Data>
<Data Name="ModuleName">WebDAVModule</Data>
<Data Name="Notification">16</Data>
<Data Name="HttpStatus">405</Data>
<Data Name="HttpReason">Method Not Allowed</Data>
<Data Name="HttpSubStatus">0</Data>
<Data Name="ErrorCode">0</Data>
<Data Name="ConfigExceptionInfo"></Data>
</EventData>
So, I uninstalled the WebDAVModule from my IIS, everything is fine now~
The IIS tracing feature is very helpful.
I tried most of the answers and unfortunately, none of them worked in completion.
Here is what worked for me. There are 3 things to do to the site you want PUT for (select the site) :
Open WebDav Authoring Rules and then select Disable WebDAV option present on the right bar.
Select Modules, find the WebDAV Module and remove it.
Select HandlerMapping, find the WebDAVHandler and remove it.
Restart IIS.
Taken from here and it worked for me:
Go to IIS Manager.
Click on your app.
Go to "Handler Mappings".
In the feature list, double click on "WebDAV".
Click on "Request Restrictions".
In the tab "Verbs" select "All verbs" .
Press OK.
I had this problem with WebDAV when hosting a MVC4 WebApi Project. I got around it by adding this line to the web.config:
<handlers>
<remove name="WebDAV" />
<add name="WebDAV" path="*" verb="*" modules="WebDAVModule"
resourceType="Unspecified" requireAccess="None" />
</handlers>
As explained here: http://evolutionarydeveloper.blogspot.co.uk/2012/07/method-not-allowed-405-on-iis7-website.html
Best to just remove the unused WebDAV feature. Go to Programs and Features => Turn Windows Features On or Off and disable WebDAV Publishing under
Internet Information Services => World Wide Web Services => Common HTTP Features
Removing the WebDAV-module should be sufficient. Just change your Web.config:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule" />
Here is what worked for me:
Open up IIS and click on your Site.
Double Click on the Modules
Right Click on WebDavPublishing and remove.
Restart running WebSite.
I was using Angular 8 and was .NET core API.
I add the following in my service web.config file. That resolve my error.
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<remove name="WebDAVModule" />
</modules>
</system.webServer>
I had the same problem, with a RESTful API running on aspnet core.
I didn't want to uninstall the WebDAV, and I tried most of the remedies described above. I tried to set the verbs="*" both on the site and on the server itself, but without success.
What did the trick for me was the following:
IIS Manager -> Sites -> MySite -> HandlerMappings -> aspNetCore -> Edit
-> Request Restrictions -> Access -> None (it was Script).
After that everything worked, even if I replaced the original WebDAV options.
Another important module that needs reconfiguring before PUT and DELETE will work is the options verb
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="OPTIONSVerbHandler" />
<remove name="WebDAV" />
<add name="OPTIONSVerbHandler" path="*" verb="*" modules="ProtocolSupportModule" resourceType="Unspecified" requireAccess="Script" />
</handlers>
Also see this post: https://stackoverflow.com/a/22018750/9376681
For whatever reason, marking WebDAVModule as "remove" in my web.config wasn't enough to fix the problem in my case.
I've found another approach that did solve the problem. If you're in the same boat, try this:
In the IIS Manager, select the application that needs to support PUT.
In the Features View, find WebDAV Authoring Rules. Double-click it, or select Open Feature from the context menu (right-click).
In the Actions pane, find and click on WebDAV Settings....
In the WebDAV Settings, find Request Filtering Behavior, and under that, find Allow Verb Filtering. Set Allow Verb Filtering to False.
In the Actions pane, click Apply.
This prevents WebDAV from rejecting verbs that it doesn't support, thus allowing a PUT to flow through to your RESTful handler unmolested.
Another tip from me. I have used PHP + IIS, and the Handler Mappings for PHP did not have the PUT verb.
Go to IIS Manager->Your site->Handler Mappings->PHPxx_via_FastCGI->Request Restrictions->Verbs, then add PUT.
That's it!
I had the same issues with PUT, PATCH and DELETE but didn't have anything with WebDav installed. Resolution 1 in this article finally helped me: http://support.microsoft.com/kb/942051
for asp.net core 5
IIS-> Sites -> MySite -> HandlerMappings -> aspNetCore -> Request Restrictions -> Access -> None (it was Script).
For me this error wouldn't go away and allow PUT methods, whatever i did.. uninstalled webdav, put configuration in web.config to remove webdav from handlers and modules, and set up PUT as an allowed verb on the request filters on iis.. and ensure iis handler mappings handling the request had PUT configured..
My problem was eventually due to bad installation of ASP.NET 4.5 Extensions. Removed everything related to asp.net from server roles and features. restarted. readded the roles and restarted. everything worked with above config.
--- The below will make PUT be accepted, but will send it to the wrong handler. --ignore the below
finally, adding PUT verb as allowed verb on TRACE handler mapping on iis worked.. since i had enabled failed error tracing, and this verb was not allowing the verb.
last time i had the same problem on another server's IIS, it was due to a missing '/' at the end of the URL since it was using a default handler without using the default document probably and now i realize that.. so check IIS handler mappings if nothing else helps.
I had this problem but nothing related to WebDAV was the issue. In my case, the client was sending a POST to www.myServer.com/api/chart. This call should be handled by the "ExtensionlessUrlHanlder-Integrated-4.0", however, somehow a local file structure was created in my server directory "...\Server\api\chart\". This meant that the "StaticFile" handler was being called instead. Deleting those local files finally solved the problem.
For Windows server 2012 -> Go to Server manager -> Remove Roles and Features -> Server Roles -> Web Server (IIS) -> Web Server -> Common HTTP Features -> Uncheck WebDAV Publishing and remove it -> Restart server.
I have a same problem for PUT and DELETE request in IIS10 for asp.net core 5.
I just added below lines in web.config and problem is resolve.
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<remove name="WebDAVModule" />
</modules>
</system.webServer>
You can do solve by other way from IIS also.
In IIS, select the application
Add rules to allow HTTP verbs in Request Filtering (But this alone doesn't work).
Go to "Modules", then select the "WebDAV Publishing" module and remove it.
Go to "Handler Mappings", then select the "WebDAV" and remove it.
in cmd run IISRESET
This is my solution, alhamdulillah it worked.
Open Notepad as Administrator.
Open this file %windir%\system32\inetsrv\config\applicationhost.config
Press Ctrl-F to find word "handlers accessPolicy"
Add word "DELETE" after word "GET,HEAD,POST".
The sentence will become <add name="PHP_via_FastCGI" path="*.php" verb="GET,HEAD,POST,DELETE"
The word "PHP_via_FastCGI" can have alternate word such as "PHP_via_FastCGI1" or "PHP_via_FastCGI2".
Save file.
Reference: https://learn.microsoft.com/en-US/troubleshoot/iis/http-error-405-website
If you are only developing on your machine, using IIS to run your application and you are not going to use WebDAV then just go to Control Panel > Add or Remove Windows features and disable WebDAV
If IIS app pool is running under classic mode, make sure you have the following in your web.config
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" modules="IsapiModule" scriptProcessor="c:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
In my case I had relocated Web Deploy to another port, which was also the IIS port (not 80). I didn't realize at first, but even though there were no errors running both under the same port, seems Web Deploy was most likely responding first instead of IIS for some reason, causing this error. I just moved my IIS binding to another port and all is well. ;)
To prevent WebDav from getting enabled at all, remove the following entry from the ApplicationHost.config:
<add name="WebDAVModule" />
The entry is located in the modules section.
Exact location of the config:
C:\Windows\System32\inetsrv\config\applicationHost.config
In case anyone still using ASP classic needs to solve the method not allowed trouble for ASP, you also need to re-register the ASP classic handler for telling it to handle additional verbs. By default, it only handles GET, HEAD and POST.
<system.webServer>
<!-- other stuff ... -->
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
<remove name="ASPClassic" />
<add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST,PUT,DELETE,PATCH" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="File" />
</handlers>
</system.webServer>
In order to remove WebDAV module and handler using appcmd you can use this:
appcmd uninstall module WebDAVModule
appcmd clear config -section:system.webServer/handlers -"[name='WebDAV']"
This can also be use in a release pipeline if needed.

Resources