Writing out child object types for collections

Jan 11, 2011 at 4:04 PM
Edited Jan 11, 2011 at 4:05 PM

Recall that Json.NET supports serialising/deserialising type information so that deserialisation works when you don't know the concrete type of the class.

I'm having some problems using this behaviour when it comes to Lists.

What I started out wanting to be able to do, on a specific property basis, is add the JsonProperty attribute to say that I want the children of this List to be serialized to JSON with their type information, i.e.


[JsonProperty(TypeNameHandling = TypeNameHandling.Auto)]
IList<IInterface> list;


What happens here is that the list itself turns into an object with a $type property and a $values array.  The objects in $values have no type information.  There are two interesting things here.  One is that the children don't get type information.  From looking at the Json.NET code, I understand why, but I still want to be able to do it :)  The second interesting thing is that clients which used to consume this JSON would now break, because the list is no longer a simple JSON Array.

So I got rid of the attribute above and set TypeNameHandling.Auto on the JsonSerializer globally for the serialisation operation.  This is not ideal for me as I prefer to control where in the JSON these type attributes will be added, especially considering that the type information which was added above fundamentally changes the JSON which is output for a list in a way that clients do not expect to parse.

In so doing, I successfully get type information written out for the child objects of the list, but the List itself still has its type written out.  I could go through all of the IList<T> properties in our code and decorate them with TypeNameHandling.None, but this feels messy and error-prone.

In the interrim I have currently made a small (yet unpleasant) change to the Json.NET library and simply stopped it writing out type information for Lists.

In the long term I think this could be better fixed in one of three ways:

  1. Decorate lists with a JsonProperty attribute in such a way that says "Write out the type information for the children of this list"
  2. Allow disable writing type information for lists (or at least offer an alternative implementation that does not deviate from the 'expected' output for a serialised enumerable)
  3. Decorate classes with an attribute specifiying that type information should always be written out when serialised (N.B. I think this would be good when it comes to CamelCase as well, so that it was not just a blanket setting for the whole serializer instance.

I would be interested to hear what people think of these approaches.