Disabling the Xml Formatter in ASP.NET Web API–The easy way

OK, I have not posted yet on the fact that WCF Web API is now reborn as ASP.NET Web API. I just did! Yes it is true. That in itself is very awesome news which I am sure many of you have already heard about. If not, go jump to Scott Gu’s blog here right now! I still have a post planned on that. Yes, I HAVE to post….later!

Moving on so that this idea doesn’t get lost in the warehouse of “to be posted” posts.

A common request people are asking is how to disable / remove the xml formatter so that their web apis ONLY return JSON regardless of the accept header.

There’s a few different common approaches to doing this, including:

Create a custom message handler which overrides accept headers. I did one a long time ago here. The handler is then registered in the config.

Remove the formatter from the collection. There’s a pretty easy way to do this as the formatters collection actually exposes an XmlFormatter property thus you can just remove it from the collection. Below is a snippet showing how to do this using the global config when hosted in ASP.NET.

var formatters = GlobalConfiguration.Configuration.Formatters;

formatters.Remove(formatters.XmlFormatter);

This evening I was reading my friend Shawn Wildermuth’s blog post “WebAPI for the MVC guy” (which you should also check out) and I saw he was using a significantly more complex variant of the second option by looping through the formatters to remove the XmlFormatter. I am sure he would not have done that had he known about the formatter hanging off of the formatters collection, however it’s probably not the most obvious.

Looking at the code I then realized there’s a third. It’s by far the least amount of code of any of the approaches I’ve seen and it’s so dead simple

What this does is remove the supported media types from the XmlFormatter. Our content negotiation algorithm looks at that collection to determine if that formatter is a match. By making it empty, well it becomes no-op.

I’m late to the party with this comment but it’s important to know that the only reason a browser defaults to displaying xml when hitting an ASP.NET Web Api Json enpoint is because the browser makes a GET request with the header “Accept: text/html”. The .Net project falls back to xml because that’s what it thinks is the best way to serve up the “html” the requester needs. You can override the header asking for text/html to return json instead of xml but I usually stick to removing the xml formatter altogether (unless xml support is required). Also, best practice would suggest always testing a Json api through a REST client such as Postman (my favorite) and not through the browser.

gabbsmo

The XML formatter have no/poor handling of dynamic and polymorphic objects. If you have any of these in you APIs you might want to disable the XML formatter to make sure that clients doesn’t use an inferior format.

It’s handy if your debugging and want to see JSON output in a web browser, by default most browsers will return XML. I prefer looking at JSON rather to XML. In a production environment though you would probably have it enabled.

http://blogs.msdn.com/gblock Glenn Block

@openid-66422:disqus

You can remove it, which I did mention as an option. It will get filtered out as it has no supported media types. I am sure the cost is not zero, but it is marginal. Totally up to you though.

http://blogs.msdn.com/gblock Glenn Block

Hi Flash, by default the first formatter in the collection is the default it will fall back to. You can change that if you want to. This post is about forcing json no matter what.

Anonymous

From your post it sounds like Web API will fall back to formatting the message as JSON if the accept header is missing/invalid. Is this true and if so, how does the Web API know which formatter to use as the default?

http://craiggwilson.myopenid.com/ Craig Wilson

Doesn’t that mean that the formatter still exists and will still get “queried” to see if it applies to the current request or response? Not that it is a lot of overhead, but still, why not just remove the formatter?