Asked  7 Months ago    Answers:  5   Viewed   84 times

I recently upgraded from Visual Studio 2010 to the Visual Studio 2012 RC. The installer also installs IIS 8 Express which Visual Studio now uses as the default web server.

IIS 8 is blocking my WEB API requests that use PUT AND DELETE verbs. IIS returns a 405 error, The requested resource does not support http method 'PUT'.

I know people have issues with this in the past and there are several messages about it on Stack Overflow. With IIS 7 Express the solution was to uninstall WebDav. Unfortunately I don't see any way to do that with IIS 8.

I've tried editing out the WebDav sections from applicationhost.config but that hasn't helped. For example I removed <add name="WebDAVModule" image="%IIS_BIN%webdav.dll" /> from the config file.

I've spent far too long on this. There must be a simple way to enable PUT and DELETE?

 Answers

46

Okay. I finally got to the bottom of this. You need to jump through some hoops to get the PUT and DELETE verbs working correctly with IIS8. In fact if you install the release candidate of VS 2012 and create a new WEB API project you'll find that the sample PUT and DELETE methods return 404 errors out of the box.

To use the PUT and DELETE verbs with the Web API you need to edit %userprofile%documentsiisexpressconfigapplicationhost.config and add the verbs to the ExtensionlessUrl handler as follows:

Change this line:

<add name="ExtensionlessUrl-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

to:

<add name="ExtensionlessUrl-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

In addition to the above you should ensure WebDAV is not interfering with your requests. This can be done by commenting out the following lines from applicationhost.config.

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

Also be aware that the default Web API convention is that your method name should be the same as the invoked HTTP verb. For example if you're sending an HTTP delete request your method, by default, should be named Delete.

Tuesday, June 1, 2021
 
Hugo
answered 7 Months ago
24

So, I checked Windows Features to make sure I didn't have this thing called WebDAV installed, and it said I didn't. Anyways, I went ahead and placed the following in my web.config (both front end and WebAPI, just to be sure), and it works now. I placed this inside <system.webServer>.

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

Additionally, it is often required to add the following to web.config in the handlers. Thanks to Babak

<handlers>
    <remove name="WebDAV" />
    ...
</handlers>
Tuesday, June 1, 2021
 
weegee
answered 7 Months ago
70

@Alexander's answer put me on the right track. Had to add the following to get DELETE/PUT handled by ASP.NET:

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="false"/>
    <handlers>
      <remove name="ExtensionlessUrl-Integrated-4.0" />
      <add name="ExtensionlessUrl-Integrated-4.0" 
           path="*." 
           verb="GET,HEAD,POST,DEBUG,DELETE,PUT" 
           type="System.Web.Handlers.TransferRequestHandler" 
           preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
Monday, August 2, 2021
 
nikosd23
answered 5 Months ago
79

We ended up going to Microsoft with this, they reviewed it for several weeks before coming back saying that it's not possible to run WebDAV and WebAPI in the same site.

They will try to address this issue in a future release of IIS.

Monday, September 20, 2021
 
simpleman
answered 3 Months ago
97

OK, this is what I ended up doing. It was actually pretty straight forward. But when you are not familiar with IIS it can be daunting.

I put the original web.config in with the node directory. I think the iisnode handler interferes with WebAPI config if you don't. So, the new node.js web.config in the node directory would look like this:

<configuration>
  <system.webServer>

    <handlers>
      <!-- indicates that the app.js file is a node.js application
           to be handled by the iisnode module -->
      <add name="iisnode" path="app.js" verb="*" modules="iisnode" />
    </handlers>

    <rewrite>
      <rules>

        <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
            <match url="^app.js/debug[/]?" />
        </rule>

      </rules>
    </rewrite>
    <httpErrors errorMode="Detailed"/>

  </system.webServer>
</configuration>

For root web.config I made it point to static files directly, bypassing node.js. Which means I'm going to have to write some custom code to handle rewrites for gzipped files - I'll figure that out later. I also added the attribute stopProcessing to each rewrite rule. This was also messing up the code, as it wouldn't actually rewrite where I wanted it too, since the rewrite would be overwritten. Note that the accept versioning header hasn't actually been tested yet - I don't have any reason to believe it wouldn't work though. The last rewrite points all uris to the webapi app by default.

In the WebAPI project I had to route all my routes to webapi/api since it isn't in the root folder. After I migrate everything from node.js I will probably make the webapi directory the root folder for the project so it won't need the webapi in my routing anymore. But this is all hidden from the client.

So here's the actual code:

<configuration>
  <system.webServer>

    <rewrite>
      <rules>

        <!-- test item for webapi folder -->
        <rule name="StaticContent2" stopProcessing="true" >
            <conditions>
                <add input="{REQUEST_URI}" pattern="^/def" />
            </conditions>
            <action type="Rewrite" url="webapi{REQUEST_URI}" />
        </rule>

        <!-- rewrite static items which exist on node -->
        <rule name="Node Static" stopProcessing="true" >
            <conditions>
                <add input="{REQUEST_URI}" pattern=".*.[A-Za-z2]{2,5}$" />
            </conditions>
            <action type="Rewrite" url="node/public{REQUEST_URI}" />
        </rule>

        <rule name="WebAPI Version 2" stopProcessing="true">
            <conditions>
                <add
                    input="{HEADER_ACCEPT}"
                    pattern="vnd.fieldops.v2"
                    ignoreCase="true"
                />
            </conditions>
            <action type="Rewrite" url="webapi{REQUEST_URI}" />
        </rule>

        <!-- rewrite to node for dynamic items -->
        <rule name="Node Dynamic" stopProcessing="true" >
            <conditions>
                <add
                    input="{REQUEST_URI}"
                    pattern="^/api/(dealerservicereports|chat|dealers|dealerequipment|dealercloseout|publications|tokens|users|?)"
                    ignoreCase="true"
                />
            </conditions>
            <action type="Rewrite" url="node/app.js" />
        </rule>

        <!-- rewrite everything else to webapi -->
        <rule name="WebAPI Dynamic" stopProcessing="true" >
            <action type="Rewrite" url="webapi{REQUEST_URI}" />
        </rule>

      </rules>
    </rewrite>
    <httpErrors errorMode="Detailed"/>

  </system.webServer>
</configuration>
Monday, October 18, 2021
 
ericstumper
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share