Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 617
Frazer Smith Avatar asked Nov 12 '22 16:11

Frazer Smith


1 Answers

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!"
      }
    ]
  }
}
like image 82
Connie Hilarides Avatar answered Nov 15 '22 06:11

Connie Hilarides