Web API Error 404 Delete Request
I have a web API that worked fine on development with all types of HTTP requests (on one controller), as soon as I moved it to production (shared server, I don't even have access to it) the DELETE
requests stopped working (others work fine ), I get 404 error:
Requested URL https://www.example.com:443/ Rejected-UrlScan ~ / API / Users / DeleteUser / 1
Physical path d: \ xx \ yy \ example.com \ Rejected-By-UrlScan
Anonymous login method
Anonymous login user
This is (part of) the web.config:
<system.web>
<customErrors mode="Off"/>
<authentication mode="None" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<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>
Action "Delete":
[Authorize]
[RoutePrefix("Users")]
public class UsersController : ApiController
{
[HttpDelete]
[Route("DeleteUser/{id:int}")]
public void Delete(int id)
{
_UsersRepository.Delete(id);
}
And the AJAX call:
deleteUser = function (id, callback) {
$.ajax({
url: "../API/Users/DeleteUser/" + id,
type: "DELETE",
success: function () {
callback;
}
});
}
WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//create json formatter and remove all others
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
jsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
config.Formatters.Remove(config.Formatters.FormUrlEncodedFormatter);
config.Formatters.Remove(config.Formatters.XmlFormatter);
}
An example of a working call on the same controller:
getUsers = function (callback) {
$.get("../API/Users/GetUsers/", callback);
}
And the action:
[Route("GetUsers")]
public IEnumerable<User> GetUsers()
{
return _UsersRepository.GetUsers();
}
source to share
I had to get it to work, so I changed the request type from DELETE
to POST
and it works fine:
[Authorize]
[RoutePrefix("Users")]
public class UsersController : ApiController
{
[HttpPost]
[Route("DeleteUser/{id:int}")]
public void Delete(int id)
{
_UsersRepository.Delete(id);
}
deleteUser = function (id, callback) {
$.ajax({
url: "../API/Users/DeleteUser/" + id,
type: "POST",
success: function () {
callback;
}
});
}
source to share
Do you have URLScan extension configured in your IIS?
https://www.iis.net/downloads/microsoft/urlscan
UrlScan is a security tool that limits the types of HTTP requests that IIS will process.
The URL Rejected by UrlScan indicates that the extension can be configured to reject Delete requests.
You can ask your administrator of the server that hosts IIS if IIS is allowed to delete requests.
source to share
The url is not correct in the JS snippet. It should be
deleteUser = function (id, callback) {
$.ajax({
url: "[Application_Path]/Users/DeleteUser/" + id,
type: "DELETE",
success: function () {
callback;
}
});
}
[RoutePrefix("Users")] overrides the default routing, so there should be no "API" in the URL.
You have to remove [Application_Path] and put your virtual directory name or use @Url.Action
source to share