Web API returns XML/JSON depending on the return value

Topics: Web Api
Sep 30, 2011 at 10:33 AM

This is the code I use to register the Web API formatters:

            var catalog = new AssemblyCatalog(typeof(MvcApplication).Assembly);
            var container = new CompositionContainer(catalog);
            var config = new WebApiConfiguration() { EnableTestClient = true };

            int numFormatters = config.Formatters.Count();
            for (int x = 0; x < numFormatters; x++)
            {
                config.Formatters.RemoveAt(0);
            } 

            config.Formatters.Insert(0, new MediaTypeFormatters.CustomJSONMediaTypeFormatter());

And this is the code of my CustomJSONMediaTyperFormatter:

    public class CustomJSONMediaTypeFormatter : MediaTypeFormatter
    {
        public CustomJSONMediaTypeFormatter()
        {
            this.AddMediaRangeMapping("*/*""text/html");
            this.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/json"));
            this.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
        }

Yes, I want to always return JSON formatting, but depending on the return value of the Web API function, sometimes it returns XML content or JSON content.

This signature returns XML:

        [WebGet(UriTemplate = "events")]
        public List<evts> EventsGet()

And this one returns JSON:

        [WebGet(UriTemplate = "events")]
        public ExtJSResult<List<evts>> EventsGet()

This is the code of my EXTJSResult class:

    public class ExtJSResult<T>
    {
        public ExtJSResult()
        {
        }
 
        public ExtJSResult(bool success, T data)
        {
            this.success = success;
            this.data = data;
        }
 
        public static ExtJSResult<T> CreateErrorResult(Dictionary<stringstring> errors)
        {
            ExtJSResult<T> returnValue = new ExtJSResult<T>();
            returnValue.success = false;
            returnValue.errors = errors;
            return returnValue;
        }
 
        public bool success { getset; }
        public T data { getset; }
        public Dictionary<stringstring> errors { getset; }
    }

 

Is this a BUG on the Web API? There is a workaround?

 

Thanks!

Coordinator
Oct 7, 2011 at 6:36 AM

My guess is that content negotiation is failing to pick your formatter and Web API ends up falling back to using XML. We have an open investigation to consider returning a 406 instead.

Could you please use Fiddler to examine the requests in both cases?

If you think this is a bug, please open an issue in Issue Tracker and provide a small project to reproduce the issue.

Thanks.

Daniel Roth

From: soycabanillas [email removed]
Sent: Friday, September 30, 2011 3:34 AM
To: Daniel Roth
Subject: Web API returns XML/JSON depending on the return value [wcf:274362]

From: soycabanillas

This is the code I use to register the Web API formatters:

            var catalog = new AssemblyCatalog(typeof(MvcApplication).Assembly);
            var container = new CompositionContainer(catalog);
            var config = new WebApiConfiguration() { EnableTestClient = true };
 
            int numFormatters = config.Formatters.Count();
            for (int x = 0; x < numFormatters; x++)
            {
                config.Formatters.RemoveAt(0);
            } 
 
            config.Formatters.Insert(0, new MediaTypeFormatters.CustomJSONMediaTypeFormatter());

And this is the code of my CustomJSONMediaTyperFormatter:

    public class CustomJSONMediaTypeFormatter : MediaTypeFormatter
    {
        public CustomJSONMediaTypeFormatter()
        {
            this.AddMediaRangeMapping("*/*", "text/html");
            this.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/json"));
            this.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
        }

Yes, I want to always return JSON formatting, but depending on the return value of the Web API function, sometimes it returns XML content or JSON content.

This signature returns XML:

        [WebGet(UriTemplate = "events")]
        public List<evts> EventsGet()

And this one returns JSON:

        [WebGet(UriTemplate = "events")]
        public ExtJSResult<List<evts>> EventsGet()

This is the code of my EXTJSResult class:

    public class ExtJSResult<T>
    {
        public ExtJSResult()
        {
        }
 
        public ExtJSResult(bool success, T data)
        {
            this.success = success;
            this.data = data;
        }
 
        public static ExtJSResult<T> CreateErrorResult(Dictionary<string, string> errors)
        {
            ExtJSResult<T> returnValue = new ExtJSResult<T>();
            returnValue.success = false;
            returnValue.errors = errors;
            return returnValue;
        }
 
        public bool success { get; set; }
        public T data { get; set; }
        public Dictionary<string, string> errors { get; set; }
    }

Is this a BUG on the Web API? There is a workaround?

Thanks!