24

I have a Web API project that returns some product data. It negotiates the return type correctly depending on the Accept header (JSON/XML) of the request. The problem is, if no Accept header is specified it returns XML, but I want it to return JSON by default

http://website.com/MyPage?type=json // returns json
http://website.com/MyPage?type=xml // returns xml
http://website.com/MyPage // returns xml by default

Here is my current code looks like:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(
new QueryStringMapping("type", "xml", new MediaTypeHeaderValue("application/xml")));

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(
new QueryStringMapping("type", "json", new MediaTypeHeaderValue("application/json")));

7 Answers 7

29

Add this in your App_Start/WebApiConfig.cs:

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
Sign up to request clarification or add additional context in comments.

3 Comments

When using Owin you need to use to the config object created in WebApiConfig.Register() with new Httpconfiguration(), and not GlobalConfiguration.Configuration More information here
Here is a link to my answer below which I include because I had to tear all my hair out to get this to work and hope to save someone the pain.
@Alastair, thank you for your contribution :). And downvoter, please be kind to leave a comment when you downvote someone.
17

I think Web API just uses the first formatter it can find in the Formatters collection. You can change the ordering with something like

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
GlobalConfiguration.Configuration.Formatters.Add(new XmlMediaTypeFormatter());

But it seems the JSON formatter should be the first one by default so you might want to check if you're already modifying this collection somewhere.

Comments

9

I think you should change as following. Global.asax:

/*For Indented formatting:*/       
 GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;

    /*Response as default json format
     * example (http://localhost:9090/WebApp/api/user/)
     */
    GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

    /*Response as json format depend on request type
     * http://localhost:9090/WebApp/api/user/?type=json
     */
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(
    new QueryStringMapping("type", "json", new MediaTypeHeaderValue("application/json")));

    /*Response as xml format depend on request type
     * http://localhost:9090/WebApp/api/user/?type=xml
     */
    GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(
    new QueryStringMapping("type", "xml", new MediaTypeHeaderValue("application/xml")));

Comments

5

Or just remove the XmlFormatter

var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);

1 Comment

Those strings must be added to your Application_Start() in Global.asax as described in official docs asp.net/web-api/overview/formats-and-model-binding/…
4

None of the above answers worked for me. The problem was that I was getting hold of the formatters from GlobalConfiguration and not the config object created with new HttpConfiguration() Here is the code that works for me :

public class WebApiConfig
{
    public static HttpConfiguration Register()
    {

        var config = new HttpConfiguration();
        // This next line could stay if you want xml formatting
        config.Formatters.Remove(config.Formatters.XmlFormatter);

        // This next commented out line was causing the problem
        //var jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;

        // This next line was the solution
        var jsonFormatter = config.Formatters.JsonFormatter;
        jsonFormatter.UseDataContractJsonSerializer = false; // defaults to false, but no harm done
        jsonFormatter.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
        jsonFormatter.SerializerSettings.Formatting = Formatting.None;
        jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();           

        // remaining irrelevant code commented out
        return config;
    }
}

Comments

2

FYI be careful of intercepting the text/html media type because this will also format the 404 responses from your server. And in my case, this led to a potential security issue because:

  • malicious user browses to http://api.mysite.com/one/two?test=%3Cscript%3Ealert(%27hi%27)%3C/script%3E
  • Web API returns the 404 object, which includes the URL. This is in JSON format because of the attribute above.
  • Browser thinks the returned object is actually text/html, so it just renders the JSON object
  • This causes the script tag embedded in the URL to execute. In my example URL above it is just an alert, but it could also be a window.location or anything sinister

Comments

0
config.EnableSystemDiagnosticsTracing();

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

// Adding formatter for Json   
config.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("type", "json", new MediaTypeHeaderValue("application/json")));

// Adding formatter for XML   
config.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("type", "xml", new MediaTypeHeaderValue("application/xml")));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.