8

I am trying to use Json.NET to serialize a subclass. The resulting json contains the serialized properties for the superclass but not the properties on the subclass object.

This seems to be related to an issue I found here on SO. But having to write a JsonConverter seems like overkill.

Sample subclass:

public class MySubclass : List<string>
{
    public string Name { get; set; }
}

Sample of the serialization:

MySubclass myType = new MySubclass() { Name = "Awesome Subclass" };
myType.Add("I am an item in the list");

string json = JsonConvert.SerializeObject(myType, Newtonsoft.Json.Formatting.Indented);

Resulting json:

[
  "I am an item in the list"
]

I expected to result to be more like this:

{
    "Name": "Awesome Subclass",
    "Items": [
        "I am an item in the list"
    ]
}

Perhaps I am just not using the right configuration when serializing. Anyone have any suggestions?

Community
  • 1
  • 1
Adam Spicer
  • 2,703
  • 25
  • 37
  • I am trying to move away from an XmlSerializer for multiple reasons, but mainly for performance. Currently I am serializing objects using an XmlSerializer and implementing `IXmlSerializable` because I have complex generic interface properties that are being serialized (which can't be deserialized without implementing `IXmlSerializable`). Json.NET is fast and it will allow me to serialize/deserialize this same object without having to do custom serialization. The downside is that I just found out it won't serialize properties on a subclass of `IEnumerable`. – Adam Spicer Jul 06 '12 at 18:59

2 Answers2

5

According the documentation:

.NET lists (types that inherit from IEnumerable) and .NET arrays are converted to JSON arrays. Because JSON arrays only support a range of values and not properties, any additional properties and fields declared on .NET collections are not serialized.

So, don't subclass List<T>, just add a second property.

public class MyClass 
{
    public List<string> Items { get; set; }
    public string Name { get; set; }

    public MyClass() { Items = new List<string>(); }
}
Paolo Moretti
  • 54,162
  • 23
  • 101
  • 92
  • Thanks for the note from the documentation. It looks like I can't use the classes that I was using for XmlSerialization unless I modify them so that they no longer inherit from an `IEnumerable` class. – Adam Spicer Jul 06 '12 at 19:09
2

Here are my thoughts on this. I would think that your expected results would be more consistent with a class like this:

public class MyClass 
{
    public string Name { get; set; }
    public List<string> Items { get; set; }
}

I would not expect to see an Items element in the serialized result for MySubclass : List<string> since there is no Items property on List nor on MySubclass.

Since your class MySubclass is actually a list of strings, I would guess (and I am just guessing here) that the SerializeObject method is merely iterating through your object and serializing a list of strings.

Kevin Aenmey
  • 13,259
  • 5
  • 46
  • 45