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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.