23

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")));
Nick Kahn
  • 19,652
  • 91
  • 275
  • 406

7 Answers7

28

Add this in your App_Start/WebApiConfig.cs:

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
Triet Doan
  • 11,455
  • 8
  • 36
  • 69
  • 1
    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](https://stackoverflow.com/questions/28552567/web-api-2-how-to-return-json-with-camelcased-property-names-on-objects-and-the/31951291#31951291) – Alastair Feb 02 '17 at 14:30
  • Here is a link to [my answer below](http://stackoverflow.com/questions/25224824/how-to-change-default-web-api-2-to-json-formatter/42005182#42005182) 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 Feb 02 '17 at 14:48
  • @Alastair, thank you for your contribution :). And downvoter, please be kind to leave a comment when you downvote someone. – Triet Doan Feb 02 '17 at 23:48
16

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.

Victor Efimov
  • 384
  • 2
  • 5
8

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")));
Stefan van de Laarschot
  • 2,154
  • 6
  • 30
  • 50
Jar Yit
  • 955
  • 11
  • 22
5

Or just remove the XmlFormatter

var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
Alex
  • 158
  • 2
  • 7
  • 1
    Those strings must be added to your Application_Start() in Global.asax as described in official docs http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#json_media_type_formatter – Deepscorn Feb 07 '16 at 02:46
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;
    }
}
Alastair
  • 439
  • 4
  • 11
1

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
Ben
  • 77
  • 11
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")));
Unheilig
  • 16,196
  • 193
  • 68
  • 98
my p30
  • 1