I have a Web API that worked perfectly on development with all kind of HTTP requests (on the same controller), once I moved it to production (shared server, I don't even have access to it) the DELETE
requests stopped working (the others are working fine), I get a 404 error:
Requested URL https://www.example.com:443/Rejected-By-UrlScan~/API/Users/DeleteUser/1
Physical Path d:\xx\yy\example.com\Rejected-By-UrlScan
Logon Method Anonymous
Logon User Anonymous
This is (a 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>
The Delete Action:
[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();
}