I\'m writing a Web API service and trying to return a (400) Bad Request if my ModelState is invalid. I do not want a response body to be attached to this. It appears that II
Try adding this to your web.config. I had a very similar problem which this solved.
<configuration>
<system.webServer>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
</configuration>
Assuming you're inside of your APIController and don't need an ExceptionFilterAttribute to do any additional work for the response, then just return a response with the error status code instead of throwing an HttpResponseException.
return Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid model.");
Usually in such cases it is enough to set TrySkipIisCustomErrors = true on response object, but in case of Web API it sometimes doesn't do the trick (Web API even tries to set this flag internally by itself). For situations like this you can consider changing the IIS configuration. Please take a look here (you should be mostly interested in existingResponse="PassThrough").
I had a situation where I was calling a WebApi endpoint from another, and having read that HttpClients should be static I made that change. Worked fine for a few dozen messages but then would get intercepted by the self-host instance which would return a 400 Bad Request. There didn't seem to be anything wrong, especially with the initial success, but my original code would add a default header to the client prior to the call. After I made the client static this would have meant that I was adding the header multiple times to the same client. I changed the code to send create and send an HttpRequestMessage instead of letting the client do it, and added the header to the request. Seems to have solved my problem.
I had the same problem with Asp.Net Webform application. The client sends ajax call to the server web handler (*.ashx).
I wanted to get the exception message back to the user. The Web handler sends back just the exception message and http status code 400.
The Trick is in Response.TrySkipIisCustomErrors = true;
try
{
//do some coding
}
catch (Exception exception)
{
Log.Error(exception);
context.Server.ClearError();
context.Response.TrySkipIisCustomErrors = true;
context.Response.ContentType = "text/plain";
context.Response.Write(exception.Message);
context.Response.StatusCode = 400;
//400 Bad Request
//The server cannot or will not process the request due to an apparent client error
//
//intentionally hidden exception
//prevent to send yellow page of death in ajax response
}
I was hitting this same condition, returning:
httpResponseMessage = context.Request.CreateResponse(statusCode);
Adding <httpErrors existingResponse="PassThrough"> didn't fix it, Content-type and the content body were missing in the response.
What did fix it was to construct the HttpResponseMessage like this:
var httpResponseMessage = context.Request.CreateResponse(statusCode, reasonPhrase);
By including the 'value' parameter (in this case, 'reasonPhrase') the Content-type and Content Body were present in the response.