title: WebAPI 405 error on DELETE
body: <p>I have been trying to get DELETE working now for over an hour and I am a little frustrated. I have tried every recommendation I can find. I have removed EVERY reference to ANYTHING WEBDAV from my applicationconfig as well as copying my whole webserver section over. I did it in steps and tried different variations and I still cannot get it to work. Yes my method is called DELETE and I added the [HttpDelete] to further make sure it knew I wanted delete support.  Any other suggestions? :/</p>
  
  <pre><code>&lt;system.webServer&gt;
      &lt;validation validateIntegratedModeConfiguration="false" /&gt;
      &lt;modules runAllManagedModulesForAllRequests="true"&gt;
        &lt;remove name="UrlRoutingModule-4.0" /&gt;
        &lt;add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" /&gt;
        &lt;remove name="FormsAuthenticationModule" /&gt;
        &lt;remove name="WebDAVModule" /&gt;
      &lt;/modules&gt;
      &lt;httpProtocol&gt;
        &lt;customHeaders&gt;
          &lt;add name="Access-Control-Allow-Origin" value="*" /&gt;
          &lt;add name="Access-Control-Allow-Headers" value="Content-Type" /&gt;
          &lt;add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /&gt;
        &lt;/customHeaders&gt;
      &lt;/httpProtocol&gt;
      &lt;handlers&gt;
        &lt;remove name="WebDAV" /&gt;
        &lt;remove name="ExtensionlessUrlHandler-Integrated-4.0" /&gt;
        &lt;remove name="OPTIONSVerbHandler" /&gt;
        &lt;remove name="TRACEVerbHandler" /&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;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;
        &lt;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" /&gt;
      &lt;/handlers&gt;
    &lt;/system.webServer&gt;
  </code></pre>
  
  <p>Tried these and more:</p>
  
  <p><a href="https://stackoverflow.com/questions/9854602/asp-net-web-api-405-http-verb-used-to-access-this-page-is-not-allowed-how/14465655#14465655">Asp.NET Web API - 405 - HTTP verb used to access this page is not allowed - how to set handler mappings</a></p>
  
  <p><a href="https://stackoverflow.com/questions/19162825/web-api-put-request-generates-an-http-405-method-not-allowed-error">Web API Put Request generates an Http 405 Method Not Allowed error</a></p>
  
  <p><a href="http://www.britishdeveloper.co.uk/2010/06/dont-use-modules-runallmanagedmodulesfo.html" rel="nofollow noreferrer">http://www.britishdeveloper.co.uk/2010/06/dont-use-modules-runallmanagedmodulesfo.html</a></p>
  
  <p>Kinda ridiculous, if M$ is going to release a product they should make sure its configured to work as expected out of the box.</p>
  
  <p>Here is the controller code, it doesn't even break in it though as the application "doesnt understand the DELETE verb". The HttpDelete I slapped on there is from System.Web.Http not the mvc one. The name is by convention but I was hoping if I stuck the attribute on it would understand anyways.</p>
  
  <pre><code>    // DELETE api/product/5
      [HttpDelete]
      public HttpResponseMessage Delete(int id)
      {
          HttpResponseMessage response = null;
  
          var product = _uow.Repository&lt;Product&gt;().ById(id);
  
          if (product == null)
              response = Request.CreateResponse(HttpStatusCode.NotFound);
  
          _uow.Repository&lt;Product&gt;().Delete(id);
          try
          {
              _uow.Save();
          }
          catch (DbUpdateConcurrencyException ex)
          {
              response = Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
          }
  
          var model = Mapper.Map&lt;ProductModel&gt;(product);
          return response ?? Request.CreateResponse(HttpStatusCode.OK, model);
      }
  </code></pre>
  
  <p>This is in my angularJs controller</p>
  
  <pre><code>    $scope.deleteProduct = function (product) {
  
          product.$delete();
          dismiss();
          //$scope.products = _.without($scope.products, product);
      };
  </code></pre>
  
  <p>This is in my angular service using $resource. (The rest of my crud is working)</p>
  
  <pre><code>minopApp.services.factory("ProductSvc", ['$resource',
  function ($resource) {
      return $resource('/api/product/:id',
          { productId: '@id' },
          {
              update: { method: 'PUT' }
          });
  }]).value('version', '0.1');
  </code></pre>
  
  <p>This is my routing inside the app.js</p>
  
  <pre><code>minopApp.config(
      ['$routeProvider',
      function ($routeProvider) {
          $routeProvider.
              when('/products', {
                  templateUrl: 'areas/product/product-list.html',
                  controller: 'ProductCtrl'
              }).
              when('/products/new', {
                  templateUrl: 'areas/product/product-create.html',
                  controller: 'ProductCtrl'
              }).
              when('/products/:id', {
                  templateUrl: 'areas/product/product-detail.html',
                  controller: 'ProductCtrl'
              }).
              when('/products/:id/edit', {
                  templateUrl: 'areas/product/product-edit.html',
                  controller: 'ProductCtrl'
              }).
              otherwise({
                  redirectTo: '/products'
              });
      }],
      ['$compileProvider',
          function ($compileProvider) {
              $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
          }]
  );
  </code></pre>