I have a RESTful WCF service that can return XML, JSON or JSONP, depending on the arguments, for example. /service.svc/stuff?format=xml or service.svc/stuff?format=json&callback=myCallback . To do this, I created a custom Behavior, MethodEncoder, and MethodEncoderFactory that handle the JSONP callback and select the author based on the format argument. In my encoder WriteMessage() method, I am doing something like
XmlWriter writer = IsXmlRequested() ? XmlDictionaryWriter.CreateTextWriter(stream) : JsonReaderWriterFactory.CreateJsonWriter(stream) message.WriteMessage(writer);
Then I define my maintenance methods as if they just return JSON, but use my own binding element:
[OperationContract, JSONPBehavior, WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "stuff") public List<Thing> GetStuff(){...}
And it almost works. When I ask for XML or JSON, I get something in the correct format, but the XML does not serialize as I expect. Here's what the XML looks like:
<root type="array"> <item type="object"> <FirstPropertyOnAThing>1</FirstPropertyOnAThing>
While if I just installed WebMessageFormat in XML, I would get something like the following:
<ArrayOfThings xmlns="...> <Thing ...> <FirstPropertyOnAThing>1</FirstPropertyOnAThing>
I definitely want the latter. I suppose this happens because the result is serialized in the dictionary when creating the Message object; my custom encoder just decides how to write this dictionary to the response stream. Thus, he gets the right encoding, but not exactly the format that has already been resolved using ResponseFormat.
First of all, is it? If so, how can I fix this? For example, can I write my own WebMessageFormat? Or do I just need to give and write separate methods (and URI patterns) that have different ResponseFormat properties for / json / * and / xml / *?
Update: In .net 4 there is the WebOperationContext.Current.OutgoingResponse.Format property, which you can simply set. I assume my problem boils down to: is there a way to do this in .net 3.5?