title: HTTP PUT not allowed in ASP.NET Web API
body: <p>On my Web API project, I cannot perform an <code>HTTP PUT</code> to my resources. I've read through <a href="https://stackoverflow.com/questions/10906411/asp-net-web-api-put-delete-verbs-not-allowed-iis-8">some</a> <a href="https://stackoverflow.com/questions/11727525/asp-net-mvc-web-api-http-put-and-delete-requests-failing">similar</a> <a href="https://stackoverflow.com/questions/9854602/asp-net-web-api-405-http-verb-used-to-access-this-page-is-not-allowed-how">questions</a> <a href="https://stackoverflow.com/questions/10099270/asp-net-web-api-returns-404-for-put-only-on-some-servers?rq=1">on</a> <a href="https://stackoverflow.com/questions/12136143/put-and-delete-returns-404-for-asp-net-webapi-in-windows-2008-server-iis-7-and-7?rq=1">this</a> <a href="http://geekswithblogs.net/michelotti/archive/2011/05/28/resolve-404-in-iis-express-for-put-and-delete-verbs.aspx" rel="nofollow noreferrer">problem</a> and I've followed the recommended advice.</p>
  
  <p>First off, I uninstalled WebDAV completely on my machine (Windows 7 64-bit) and subsequently rebooted my machine.</p>
  
  <p>Secondly, the WebDAV handlers were specified as removed in my <code>web.config</code> and the <code>HTTP PUT</code> verb was specified as being allowed for the Extensionless URL Handler.</p>
  
  <pre><code>&lt;modules runAllManagedModulesForAllRequests="false"&gt;
    &lt;remove name="WebDAVModule"/&gt;
  &lt;/modules&gt;
  
  &lt;handlers&gt;
    &lt;remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" /&gt;
    &lt;remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" /&gt;
    &lt;remove name="ExtensionlessUrlHandler-Integrated-4.0" /&gt;
    &lt;remove name="WebDAV"/&gt;
    &lt;add name="ExtensionlessUrlHandler-Integrated-4.0"
         path="*."
         verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
         type="System.Web.Handlers.TransferRequestHandler"
         resourceType="Unspecified"
         requireAccess="Script"
         preCondition="integratedMode,runtimeVersionv4.0" /&gt;
    &lt;add name="AttributeRouting" path="routes.axd" verb="*" type="AttributeRouting.Web.Logging.LogRoutesHandler, AttributeRouting.Web" /&gt;
  &lt;/handlers&gt;
  </code></pre>
  
  <p>I even tried adding the ISAPI Extensionless URL Handler (32-bit and 64-bit) and changing my application from the integrated pipeline App Pool to the classic App Pool.</p>
  
  <pre><code>&lt;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" /&gt;
  &lt;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" /&gt;
  </code></pre>
  
  <p>I'm currently using <a href="http://nuget.org/packages/Thinktecture.IdentityModel" rel="nofollow noreferrer">Thinktecture IdentityModel</a> to enable Cross Origin Resource Sharing (CORS) support. For my sanity, I've gone with the nuclear option of enabling everything to make sure the <code>HTTP PUT</code> is actually allowed.</p>
  
  <pre><code>config.RegisterGlobal(httpConfig);
  
  config.ForAllResources()
        .ForAllOrigins()
        .AllowAllMethods()
        .AllowAllRequestHeaders();
  </code></pre>
  
  <p>The <a href="http://attributerouting.net/" rel="nofollow noreferrer">Attribute Routing</a> NuGet package is configured to pick up all routes from the current assembly and any subtypes of <code>ApiController</code>.</p>
  
  <pre><code>config.AddRoutesFromAssembly(Assembly.GetExecutingAssembly());
  config.AddRoutesFromControllersOfType&lt;ApiController&gt;();
  </code></pre>
  
  <p>My resource has the <code>PUT</code> attribute properly specified as well.</p>
  
  <pre><code>[PUT("/API/Authenticate/Link/{key}/{identifier}")]
  public Boolean LinkUser(Guid key, String identifier) { ... }
  </code></pre>
  
  <p>Every resource I look up on this matter recommends the same exact thing: Uninstalling WebDAV, disabling the WebDAV handlers and making sure that the Extensionless URL handler is properly configured. I've done all that and it <strong>still</strong> doesn't work. </p>
  
  <p>In fiddler, I'm getting the following:</p>
  
  <pre><code>PUT https://localhost/Test/API/Authenticate/Link/Foo/Bar
  
  {"Message":"The requested resource does not support http method 'PUT'."}
  </code></pre>
  
  <p>What am I doing wrong?</p>