If a request is made to my Web API service that has a Content-Type
header containing a type not supported by that service, it returns a 500 Internal Server Error
status code with a message similar to the following:
{"Message":"An error has occurred.","ExceptionMessage":"No MediaTypeFormatter is available to read an object of type 'MyDto' from content with media type 'application/UnsupportedContentType'.","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger)
at System.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger)
at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger)
at System.Web.Http.ModelBinding.FormatterParameterBinding.ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
at System.Web.Http.Controllers.HttpActionBinding.<>c__DisplayClass1.<ExecuteBindingAsync>b__0(HttpParameterBinding parameterBinder)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Threading.Tasks.TaskHelpers.IterateImpl(IEnumerator`1 enumerator, CancellationToken cancellationToken)"}
I would instead prefer to return a 415 Unsupported Media Type
status code as recommended, e.g, here.
How do I configure my service to do this?
Here is the solution I came up with to this problem.
It's broadly based on the one described here for sending a 406 Not Acceptable status code when there's no acceptable response content type.
public class UnsupportedMediaTypeConnegHandler : DelegatingHandler {
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken) {
var contentType = request.Content.Headers.ContentType;
var formatters = request.GetConfiguration().Formatters;
var hasFormetterForContentType = formatters //
.Any(formatter => formatter.SupportedMediaTypes.Contains(contentType));
if (!hasFormetterForContentType) {
return Task<HttpResponseMessage>.Factory //
.StartNew(() => new HttpResponseMessage(HttpStatusCode.UnsupportedMediaType));
}
return base.SendAsync(request, cancellationToken);
}
}
And when setting up your service config:
config.MessageHandlers.Add(new UnsupportedMediaTypeConnegHandler());
Note that this requires that that the char sets match as well. You could loosen this restriction by checking only the MediaType
property of the header.
There is no configuration flag that would automatically change the status code. You could create a MessageHandler which could probably check the "response being sent out" and modify the status code to 415.
The standard way to return status code is to return a HttpResponseMessage from your action. Instead of Raw content you can wrap the content in a HttpResponseMessage object and set the status like this:
public System.Net.Http.HttpResponseMessage Getresponse()
{
return new System.Net.Http.HttpResponseMessage() { Content = new System.Net.Http.StringContent(done.ToString()), StatusCode = System.Net.HttpStatusCode.Conflict };
}
来源:https://stackoverflow.com/questions/12098097/how-do-i-configure-the-status-code-returned-by-my-asp-net-web-api-service-when-t