The Light
The Light

Reputation: 27011

How to return Xml rather than JSON from a Web API Action?

How to configure the actions within a Web API Controller, to return XML rather than JSON?

I have an action which returns a UserProfile object which has XmlElement attributes:

[HttpGet]
        public UserProfile SearchByEmail(string siteName, string email)
        {
            var userProfile = this._profileFinderByEmail.Find(siteName, email);

            if (userProfile == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return userProfile;
        }

When when I run this action, it returns application/json rather than xml. How could I return xml?

Judging by Fiddler the request header that I was sending had the below Accept header key:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

that I expected it to return xml but it doesn't.

How to fix it?

I've also set the below value in the WebApiConfig class:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;

Viewing from Chrome/Network tab, I can see the below error:

Status Code:406 Not Acceptable

Upvotes: 0

Views: 4095

Answers (1)

tpeczek
tpeczek

Reputation: 24125

The header looks correct, so first you should check if the formatter is there. You can output all the registered formatters with following snippet (you can use it inside of your action method):

foreach (var formatter in GlobalConfiguration.Configuration.Formatters)
{
    System.Diagnostics.Debug.WriteLine(String.Format("{0}: {1}", formatter.GetType().Name, String.Join(", ", formatter.SupportedMediaTypes.Select(x=>x.MediaType))));
}

The results will be visible in Output window of Visual Studio (set Show output from to Debug). You should look for line like this:

XmlMediaTypeFormatter: application/xml, text/xml

If it is not there then it means that it was somehow removed and you need to find that part of code in your application. If it is there then it most probably means that DataContractSerializer wasn't able to serialize your entity (you can read more about the supported types here).

You also mentioned that you are using XmlElement attributes in your entity. By default XmlMediaTypeFormatter is using DataContractSerializer (as mentioned above) which will ignore those attributes. If you want to switch it to XmlSerializer you can use following code (for example in your Global.asax):

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;

Of course XmlSerializer has its own set of limitations which you need to be aware of.

Upvotes: 1

Related Questions