How do I configure the status code returned by my ASP.NET Web API service when the request has an unsupported Content-Type?

ⅰ亾dé卋堺 提交于 2019-12-07 08:20:49

问题


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?


回答1:


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.




回答2:


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.




回答3:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!