Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebAPI not returning XML even with correct Accepts header

I'm using ASP.NET WebAPI RC, and hosting an API controller with nothing fancy about it. Everything works fine with JSON, but I'm testing requesting different formats using the Accepts header, and that's where I'm having trouble.

I'm using jQuery to issue an AJAX request, and setting the 'dataType' parameter of the request. This correctly sets the appropriate Accept header as you will see below.

$.ajax({     type: method,     url: url,     dataType: "xml",     data: data || null,     success: function (data) {         // omitted     } }); 

Here is a save of the fiddler request/response. As you can see the Accept header says application/xml, but WebAPI returned JSON. I have also tried manually setting the Accept header to just "application/xml" (so it doesn't have the text/html stuff as well), but to no avail.

What the heck am I missing? (note: I've snipped some confidential info in the data but didn't tweak it otherwise)

GET http://localhost/insp**snip**6716 HTTP/1.1 Host: localhost Connection: keep-alive X-Requested-With: XMLHttpRequest User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1 Accept: application/xml, text/xml, */*; q=0.01 Referer: http://localhost/inspector/api/test? Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 Cookie: m=34e2:|2c69:t|47ba:t|4e99:t; .INSPECTOR3COOKIE=08BA683091E2A457B1832E9B*snip*F911D9ED97076   HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Type: application/json; charset=utf-8 Expires: -1 Server: Microsoft-IIS/7.5 X-AspNet-Version: 4.0.30319 Persistent-Auth: true X-Powered-By: ASP.NET Date: Fri, 03 Aug 2012 22:27:42 GMT Content-Length: 1816  {"Id":2416716,"ProjectId":36,"Url":"http://ins *snip, but obviously this is JSON not XML * 

I'd like to point out I'm not tweaking any formatters in AppStart or anything, so as far as I understand, the JSON and XML formatters should be enabled by default.

UPDATE: I figured it out -- check my own answer below

like image 923
InfinitiesLoop Avatar asked Aug 03 '12 22:08

InfinitiesLoop


People also ask

Can Webapi return XML?

the Web API 2 framework defaults to XML but uses the client's accept header to determine the return type format. If XML is required for every response then configure Web API to always return XML.

What is Web API Accept header?

The Accept header attribute specifies the format of response data which the client expects and the Content-Type header attribute specifies the format of the data in the request body so that receiver can parse it into appropriate format.


2 Answers

I figured it out!

I had this in my AppStart, because I wanted the Xml serializer not the DataContract serializer:

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

HOWEVER... apparently there is something about my model that makes the Xml Serializer think it can't serialize it. I am guessing that is causing WebAPI to decide to use the JSON formatter instead.

It's completely non-intuitive that this harmless looking setting could actually affect which formatter is used. Hope the WebAPI people see this :)

Some kind of tool that let you understand the inputs and outputs of content negotiation process so you can debug issues like this would be nice.

like image 124
InfinitiesLoop Avatar answered Oct 17 '22 05:10

InfinitiesLoop


I had the same issue but fixed it by adding default constructors to all the models that I was returning.

The XML serializer creates blank model objects and then populates it via the setters on the properties. If the setters are protected or private then that property will not get serialized either

like image 31
Kevin Brady Avatar answered Oct 17 '22 04:10

Kevin Brady