ASP.NET MVC 4 RC & ASP.NET Web API: Return “HTTP Status code 4xx” instead of throwing InvalidOperationException “No MediaTypeFormatter is available to read an object of type ‘[…]’ from content with media type ‘[…]'”

By default ASP.NET Web API (included in ASP.NET MVC 4) throws the following exception when trying to process a request with an unsupported content-type (like “text/plain”):

System.InvalidOperationException
No MediaTypeFormatter is available to read an object of type ‘[…]’ from content with media type ‘[…]’.

IMHO, sending a wrong content-type is a client-side error, and the server should return a HTTP response with an appropriate HTTP status code instead of throwing the exception (on the server side).

To send a HTTP response with status code “415 (Unsupported Media Type)” to the client you can use the following custom DelegationHandler (the implementation is based on http://stackoverflow.com/questions/12098097/how-do-i-configure-the-status-code-returned-by-my-asp-net-web-api-service-when-t#12099486):

public class UnsupportedMediaTypeDelegatingHandler : DelegatingHandler
{
  protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
  {
    if (request != null && request.Content != null && request.Content.Headers != null && request.Content.Headers.ContentType != null)
    {
      var mediaType = request.Content.Headers.ContentType.MediaType;
      var formatters = request.GetConfiguration().Formatters;
      var hasFormatterForContentType = formatters.Any(formatter => formatter.SupportedMediaTypes.Any(e => e.MediaType == mediaType));
 
      if (!hasFormatterForContentType)
      {
        var message = string.Format("The requested resource does not support content type '{0}'.", mediaType);
        return Task.Factory.StartNew(() => new HttpResponseMessage(HttpStatusCode.UnsupportedMediaType) {
          Content = new StringContent(message)
        });
      }
    }
 
    return base.SendAsync(request, cancellationToken);
  }
}

In detail, the DelegationHandler tests if a Formatter exists (by default the formatters JsonFormatter and XmlFormatter are enabled) that could handle the content type defined in the client’s request. If no such Formatter is found, the DelegationHandler stops the processing of the request and sends the “415 (Unsupported Media Type)” response to the client.

In a last step, the custom DelegationHandler needs to be activated by adding the following line in the file Global.asax.cs:

protected void Application_Start()
{
  [...]
  GlobalConfiguration.Configuration.MessageHandlers.Add(new UnsupportedMediaTypeDelegatingHandler());
  [...]
}

Comments

  1. Etienne

    Thanks a lot, very useful!!

Leave a comment

Your email address will not be published. Required fields are marked *

*