Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DELETE/PUT verbs result in 404 Not Found in WebAPI, only when running locally

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:

I've added the following under <system.webServer /> in my WebAPI web.config:

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule" />
    </modules>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

I've followed the instructions at: http://geekswithblogs.net/michelotti/archive/2011/05/28/resolve-404-in-iis-express-for-put-and-delete-verbs.aspx, which basically say to modify the ExtensionlessUrlHandler-Integrated-4.0 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.

I've done an IIS reset.

Here's my MVC5 front end code that calls the WebAPI delete method - please note that when I manually navigate to api/bulletinboard/get/{0} where {0} is an integer, I get a valid JSON response. Below, contactUri is http://localhost/SiteName/api/bulletinboard/get/53 which returns valid JSON:

[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");
            }
        }

Here's my WebAPI delete method:

[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);
        }

Here's my WebApiConfig.cs in my WebAPI project:

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());
        }

QUESTION: What else can I try to resolve this error? This works fine when deployed from my local environment to my company's development servers.

like image 436
Mike Marks Avatar asked Jan 15 '14 14:01

Mike Marks


4 Answers

Mark Jensen solution worked for me.

Just changed my Application Pool from "Classic" to "Integrated" and my requests worked.

like image 125
Marco Carvalho Avatar answered Oct 11 '22 20:10

Marco Carvalho


If you are using IIS, make sure you have the HTTP Verb set to allowed in Request Filtering. If its not there, you can set it to allow it on the side.

enter image description here

like image 38
Kalel Wade Avatar answered Oct 11 '22 20:10

Kalel Wade


This issue can be fixed by IIS level configuration- Open IIS->select your website->IIS (section) ->Request Filtering ->HHTP Verbs

Remove DELETE verb/ OR allow DELETE verb

Issue will get resolved.

like image 44
Yogesh Patil Avatar answered Oct 11 '22 20:10

Yogesh Patil


We were struggling with DELETE/PUT returning 404 errors on IIS 8. We did all of the above answers changing web.config to accept all Verbs, enabling put/delete in the request filtering. We had also disabled webDAV multiple ways. We found that the application pool was set to classic verses integrated (what it should have been). Now DELETE/PUT verbs work fine.

like image 29
Mark Jensen Avatar answered Oct 11 '22 22:10

Mark Jensen