Frazer Smith
Frazer Smith

Reputation: 71

JSON serialization: class contains a generic collection of generic types

I am trying to serialize a .NET class to JSON which contains a property which is a generic list of generic types.

My generic type is defined as follows:

public interface IFoo {}

public class Foo<T>: IFoo
{
  public string Name {get; set;}
  public string ValueType {get; set;}
  public T Value {get; set:}

    public Foo(string name, T value)
    {
      Name = name;
      Value = value;
      ValueType = typeof(T).ToString();
    }
}

Then, as follows:

public class Fum
{
  public string FumName {get; set;}
  public list<IFoo> Foos {get; set;}
}

I create instances as follows:

myFum = new Fum();
myFum.FumName = "myFum";
myFum.Foos.Add(new Foo<int>("intFoo", 2);
myFum.Foos.Add(new Foo<bool>("boolFoo", true);
myFum.Foos.Add(new Foo<string>("stringFoo", "I'm a string");

then...

I am attempting to use the NewtonSoft JSON library to serialize as follows:

string strJson = JsonConvert.SerializeObject(data, 
                  Formatting.Indented, new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Include,
            TypeNameHandling = TypeNameHandling.All,
            TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
        });

In the resulting JSON string, Name and ValueType properties for each Foo instance are correctly serialized - however, Value is always omitted from the output:

{
  "FumName": "myFum",
  "Foos" : [
    {
      "Name": "intFoo",
      "ValueType": "System.Int32"
    },
    {
      "Name": "boolFoo",
      "ValueType": "System.Boolean"
    },
    {
      "Name": "stringFoo",
      "ValueType": "System.String"
    }
  ]
}

Can anyone suggest an approach that will allow me to correctly serialize the list of generic type instances so that Value properties are included?

Upvotes: 5

Views: 5677

Answers (1)

Connie Hilarides
Connie Hilarides

Reputation: 1735

Json.NET may ignore generic types by default, marking it with the [JsonProperty] attribute could fix the issue. Just a thought, it may or may not work. I can't test it right now but I will try it and tell you if it actually works.

Edit: I think it may be the version of json.net you are using, because I just tested your code with the version from NuGet and recieved the following output:

{
  "$type": "Testing.Fum, Testing",
  "FumName": "myFum",
  "Foos": {
    "$type": "System.Collections.Generic.List`1[[Testing.IFoo, Testing]], mscorlib",
    "$values": [
      {
        "$type": "Testing.Foo`1[[System.Int32, mscorlib]], Testing",
        "Name": "intFoo",
        "ValueType": "System.Int32",
        "Value": 2
      },
      {
        "$type": "Testing.Foo`1[[System.Boolean, mscorlib]], Testing",
        "Name": "boolFoo",
        "ValueType": "System.Boolean",
        "Value": true
      },
      {
        "$type": "Testing.Foo`1[[System.String, mscorlib]], Testing",
        "Name": "stringFoo",
        "ValueType": "System.String",
        "Value": "I'm a string!"
      }
    ]
  }
}

Upvotes: 1

Related Questions