Custom XML Media type formatter

Topics: Web Api
Sep 2, 2011 at 10:14 AM

I want to use a customized XMLSerilizer in an formatter for "application/xml" media types.

I´ve created a formatter, which adds the proper "SupportedMediaTypes". But the client requests get

redirected to the default XMLFormatter.


What can i do?


Background: i want to create hypermedia-based xml responses, see

Sep 2, 2011 at 10:29 PM

Are you using the latest bits released yesterday?  If so you need to change your MediaTypeFormatter to derive from XmlMediaTypeFormatter.  There is some magic that will stop the default formatter from getting inserted into the formatter collection if your class derives from XmlMediaTypeFormatter.  Yes, seems crazy to me too!


If you are using earlier bits, then you need to make sure you "insert" your formatter into the beginning of the collection, rather than the end, so that your formatter gets priority.

Sep 4, 2011 at 9:36 PM

humbrie/Darrrel you don't need to derive, you can insert your formatter to the beginning of the list so that it gets picked up. The collection exposes an Insert method, call it using 0 as the position.

Oct 4, 2011 at 5:55 PM

Unfortunaly this applies not entirely. If you use a user agent like a browser, which accepts */* the MS XMLserializer will be used by default.

Even if i remove it from the Formatters collection, it gets still serialized with the build-in serializer. I gues this is because of this property: WebApiConfiguration.Formatters.XmlFormatter ? Unfortunaly, I cannot replace it, because the setter is missing (or private)...

Oct 4, 2011 at 7:53 PM

Did you try inserting your custom formatter to the beginning of the collection?


Oct 10, 2011 at 7:18 PM
Edited Oct 10, 2011 at 7:24 PM

EDIT: I guess this is related to this issue:


Yes, i did. I can see the Formatter Collection altered, when the server is starting. But i dont know, why it´s still not working...

snippet of global.asax


        protected void Application_Start(object sender, EventArgs e)
            // Set configuration & routes
            RouteTable.Routes.MapServiceRoute<HomeController>(HomeController.ResourcePath, WebApiConfiguration);

        private static WebApiConfiguration _WebApiConfiguration;
        private static WebApiConfiguration WebApiConfiguration
                if (_WebApiConfiguration == null)
                    _WebApiConfiguration = new WebApiConfiguration { EnableHelpPage = true, EnableTestClient = true };
                    _WebApiConfiguration.Formatters.Insert(0, new HalMediaTypeFormatter());
                return _WebApiConfiguration;




this is a snippet of the media tpye formatter:


    public class HalMediaTypeFormatter : MediaTypeFormatter
        public const string HalXmlMediaType = "application/hal+xml";
        public const string XmlMediaType = "application/xml";
        public const string XmlTextMediaType = "text/xml";

        public HalMediaTypeFormatter(XmlSerializerNamespaces namespaces=null)
            Namespaces = namespaces;
            const string charset = "utf-8";

            SupportedMediaTypes.Add(new MediaTypeHeaderValue(HalXmlMediaType) { CharSet = charset });
            SupportedMediaTypes.Add(new MediaTypeHeaderValue(XmlMediaType) { CharSet = charset });
            SupportedMediaTypes.Add(new MediaTypeHeaderValue(XmlTextMediaType) { CharSet = charset });
Oct 10, 2011 at 8:33 PM


Is it possible to get the Fiddler trace?

Regarding your issue, Can you try after making the following change in your custom media type formatter? Fyi...I removed the CharSet information here.

SupportedMediaTypes.Add(new MediaTypeHeaderValue(HalXmlMediaType));
SupportedMediaTypes.Add(new MediaTypeHeaderValue(XmlMediaType));
SupportedMediaTypes.Add(new MediaTypeHeaderValue(XmlTextMediaType));


Kiran Challa

Oct 11, 2011 at 1:33 PM

Also be aware that content negotiation does not automatically match media ranges like */*.  It is likely asking your custom formatter if it supports "*/*", finding no match, and moving on.  We are currently discussing how to better handle the case of matching no formatters, but I believe this is why you see the default Xml formatter come into play.   It found not formatters and chose that as the backstop.

I'd recommend you look into the MediaTypeFormatter.MediaTypeMappings collection.   I believe you want to add a 'new MediaRangeMapping("*/*", "application/xml")' (or whatever) to your custom formatter.   Then, when a media range like "*/*" comes through, your formatter will be picked.

Ron Cain


Oct 11, 2011 at 2:34 PM
Edited Oct 11, 2011 at 2:34 PM

Well, i´ll try that (both)! From my point of view, i would expect, that any mediatype range would be handled by the framework by going through the formatters collection and choosing which type matches first (in case of */* it would be obviously the first formatter in the collection).

A more complex scenario: If i´d have only one formatter in the list, like "application/atom+xml" and the client wants a "application/xml"...

What would the server do?

Sending atom (which is surely valid xml)?

With which media type declaration?

"application/atom+xml" would be correct, but this is not, what the client would likely expect.

As far as i know, there is no "media type specialization/derivation/inheritance" concept defined, which would apply to this scenario.

(i´ve already started a thread weeks ago on the rest-discuss group)