Mike Marks Mike Marks - 3 months ago 30
ASP.NET (C#) Question

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.

Answer

What I did was just switch from using local IIS to IIS Express via the project properties on my WebAPI project, as a workaround. Doing this and deleting a record then resulted in a 405 Method Not Allowed error. I then changed the lines of code:

response = client.GetAsync(string.Format("api/bulletinboard/get/{0}", id)).Result;
contactUri = response.RequestMessage.RequestUri;
response = client.DeleteAsync(contactUri).Result;

To:

response = client.DeleteAsync(string.Format("api/bulletinboard/delete/{0}", id)).Result;

This is very strange because I have another project that runs the first block of code and it deletes records just fine. Anyways, this resolved my local problem. I understand this doesn't really resolve my main issue which was using local IIS, but this workaround worked for me.

Comments