More Problems with Formatters

Topics: Web Api
Oct 28, 2011 at 8:29 PM

While, I'm not entirely sure there isn't a problem with my code (because I'm doing some crazy things) I think there may be more issues with formatters. It seams that, in some circumstances, the wrong formatter is being selected. Even though the only formatter I specify is a custom Json formatter, some times my representations are formatted as Xml. There appears to be a connection to the fact that the class implement IXmlSerializable or has some Xml attributes on it, though it's not always the case. What is really strange is that the response type will come back as Json, but the content will be formatted as Xml. I was able to clear up the issue by not implementing IXmlSerializable on my type. In this case it's ok, because the customer decided they wanted to use Json. However, previously we supported both Json and Xml.

-I'm using the latest code from the repository. As I mentioned, my custom formatter is called sometimes, and sometimes it is not. It appears to always be called on the client side, but not always on the server side.

Oct 29, 2011 at 6:57 AM

I noticed the same thing today as well.  Local build from the source. Seems to be intermittent since when I debug I don't hit any breakpoints for OnRead or OnWrite.  Even though I'm using a JSON.Net custom formatter, serialization seems to bork on my List<T> within WCF despite the fact that I've cleared all other formatters and want it to leave serializing and deserializing exclusively to JSON.Net.  Don't know if it's the same issue you're having EisenbergEffect, but I'm stumped as to how to proceed.

In case it helps, here something like what I'm doing:

public abstract class Event
{
   public Guid Id {get;set;}
}

public class Event1 : Event
{
   public string Event1Property {get;set;}
}

public class Event2 : Event
{
  public string Event2Property {get;set;}
}


// Resource
public List<Event> List()
{
  return new List<Event>{new Event1(), new Event2()};
}

Neither the default XML or JSON serializers know what to do with this (I'm JSON only as well).  This worked perfectly with my custom JSON.Net serializer issue using Preview 4.

...brent

Nov 4, 2011 at 11:33 PM

Eisenberg, the behavior you are seeing is in fact documented here:

http://msdn.microsoft.com/en-us/library/bb412170.aspx

XML Types and JSON

XML types become JSON strings.

  • For example, if a data member "q" of type XElement contains <abc/>, the JSON is {"q":"<abc/>"}.
  • There are some special rules that specify how XML is wrapped - for more information, see the Advanced Information section later in this topic.

XML in JSON Strings

XmlElement

XmlElement is serialized as is, with no wrapping. For example, data member "x" of type XmlElement that contains <abc/> is as represented as follows.

{"x":"<abc/>"}

IXmlSerializable Types including XElement and DataSet

ISerializable types subdivide into "content types", "DataSet types" and "element types". For definitions of these types, see XML and ADO.NET Types in Data Contracts.

"Content" and "DataSet" types are serialized similar to Array objects of XmlNode discussed in the previous section. They are wrapped in an element whose name and namespace corresponds to the data contract name and namespace of the type in question.

"Element" types such as XElement are serialized as is, similar to XmlElement previously discussed in this topic

 

So IXmlSerializable types get handled as XML for the roundtrip to work. You may want to consider marking your types as [Serializable]/[DataContract] instead, or you may want to capture the IXmlSerializable logic elsewhere in a method that turns your object into an XmlElement or XElement for consumption by XmlSerializer or DataContractSerializer.