title: DELETE/PUT verbs result in 404 Not Found in WebAPI, only when running locally
body: <p>I know this is a commonly addressed issue, and I've done everything that many posts here on SO suggest.  When I try to delete a record using WebAPI (version 2) from my MVC5 front end running under local IIS, I get a 404 Not Found response.  Here are the things I've tried:</p>
  
  <p>I've added the following under <code>&lt;system.webServer /&gt;</code> in my WebAPI web.config:</p>
  
  <pre><code>&lt;system.webServer&gt;
      &lt;validation validateIntegratedModeConfiguration="false" /&gt;
      &lt;modules runAllManagedModulesForAllRequests="true"&gt;
        &lt;remove name="WebDAVModule" /&gt;
      &lt;/modules&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;add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /&gt;
      &lt;/handlers&gt;
    &lt;/system.webServer&gt;
  </code></pre>
  
  <p>I've followed the instructions at: <a href="http://geekswithblogs.net/michelotti/archive/2011/05/28/resolve-404-in-iis-express-for-put-and-delete-verbs.aspx" rel="noreferrer">http://geekswithblogs.net/michelotti/archive/2011/05/28/resolve-404-in-iis-express-for-put-and-delete-verbs.aspx</a>, which basically say to modify the <code>ExtensionlessUrlHandler-Integrated-4.0</code> in IIS "Handler Mappings".  It says to double click on the handler, click "Request Restrictions", and "Allow PUT and DELETE verbs".  I've done this, and I still get the 404 error.</p>
  
  <p>I've done an IIS reset.</p>
  
  <p>Here's my MVC5 front end code that calls the WebAPI delete method - please note that when I manually navigate to <code>api/bulletinboard/get/{0}</code> where <code>{0}</code> is an integer, I get a valid <code>JSON</code> response.  Below, <code>contactUri</code> is <code>http://localhost/SiteName/api/bulletinboard/get/53</code> which returns valid <code>JSON</code>:</p>
  
  <pre><code>[HttpPost, ActionName("Delete")]
          public ActionResult Delete(string appId, int id)
          {
              response = client.GetAsync(string.Format("api/bulletinboard/get/{0}", id)).Result;
              contactUri = response.RequestMessage.RequestUri;
              response = client.DeleteAsync(contactUri).Result;
  
              if (response.IsSuccessStatusCode)
              {
                  return RedirectToAction("MessageList", new { appId = appId });
              }
              else
              {
                  LoggerHelper.GetLogger().InsertError(new Exception(string.Format(
                      "Cannot delete message due to HTTP Response Status Code not being successful: {0}", response.StatusCode)));
                  return View("Problem");
              }
          }
  </code></pre>
  
  <p>Here's my WebAPI delete method:</p>
  
  <pre><code>[HttpDelete]
          public HttpResponseMessage Delete(int id)
          {
              BulletinBoard bulletinBoard = db.BulletinBoards.Find(id);
              if (bulletinBoard == null)
              {
                  return Request.CreateResponse(HttpStatusCode.NotFound);
              }
  
              db.BulletinBoards.Remove(bulletinBoard);
  
              try
              {
                  db.SaveChanges();
              }
              catch (DbUpdateConcurrencyException ex)
              {
                  return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
              }
  
              return Request.CreateResponse(HttpStatusCode.OK, bulletinBoard);
          }
  </code></pre>
  
  <p>Here's my WebApiConfig.cs in my WebAPI project:</p>
  
  <pre><code>public static void Register(HttpConfiguration config)
          {
              // Web API configuration and services
              config.EnableCors();
  
              // Web API routes
              config.MapHttpAttributeRoutes();
  
              config.Routes.MapHttpRoute(
                  name: "ApiWithActionName",
                  routeTemplate: "api/{controller}/{action}/{id}",
                  defaults: new { id = RouteParameter.Optional }
              );
  
              config.Routes.MapHttpRoute(
                  name: "DefaultApi",
                  routeTemplate: "api/{controller}/{id}",
                  defaults: new { id = RouteParameter.Optional }
              );
  
              var json = config.Formatters.JsonFormatter;
              json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
              config.Formatters.Remove(config.Formatters.XmlFormatter);
  
              config.Formatters.Add(new PlainTextFormatter());
          }
  </code></pre>
  
  <p><strong>QUESTION</strong>: What else can I try to resolve this error?  This works fine when deployed from my local environment to my company's development servers.</p>