When I try to serialize and deserialize a property of type Dictionary<string, List<MyInterface>>
, Newtonsoft doesn't add the $type property in the IMyInterface even if I set the attribute [JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto, TypeNameHandling = TypeNameHandling.Auto)]
Sample :
static void Main(string[] args)
{
Data data = new Data();
data.Rows.Add("key", new List<IMyInterface>() { new MyInterfaceImplementation() { SomeProperty = "property" } });
string serialized = JsonConvert.SerializeObject(data);
Data deserialized = JsonConvert.DeserializeObject<Data>(serialized);
}
public class Data
{
public Data()
{
this.Rows = new Dictionary<string, List<IMyInterface>>();
}
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto, TypeNameHandling = TypeNameHandling.Auto)]
public Dictionary<string, List<IMyInterface>> Rows { get; private set; }
}
public interface IMyInterface
{
string SomeProperty { get; set; }
}
public class MyInterfaceImplementation : IMyInterface
{
public string SomeProperty { get; set; }
}
If I set a the global settings TypeNameHandling = TypeNameHandling.Auto
when serializing and deserializing, it works.
I found this issue that is really similar to mine http://json.codeplex.com/workitem/18046 and that is supposed to be fixed since 2010, but if I run his sample, it also crashes like me.
ItemTypeNameHandling = TypeNameHandling.Auto on your Rows property applies to the contents of the dictionary (i.e. List<>), not the contents of the list.
public class DataType
{
public DataType()
{
Rows = new Dictionary<string, IEnumerable<IMyInterfaceType>>();
}
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto, TypeNameHandling = TypeNameHandling.Auto)]
public Dictionary<string, IEnumerable<IMyInterfaceType>> Rows { get; private set; }
}
public interface IMyInterfaceType
{
string SomeProperty { get; set; }
}
public class MyInterfaceImplementationType : IMyInterfaceType
{
public string SomeProperty { get; set; }
}
[Test]
public void GenericItemTypeCollection()
{
DataType data = new DataType();
data.Rows.Add("key", new List<MyInterfaceImplementationType> { new MyInterfaceImplementationType() { SomeProperty = "property" } });
string serialized = JsonConvert.SerializeObject(data, Formatting.Indented);
DataType deserialized = JsonConvert.DeserializeObject<DataType>(serialized);
Assert.AreEqual("property", deserialized.Rows["key"].First().SomeProperty);
}
Your test case doesn't cover my use case. I have multiple implementations of IMyInterfaceType
that I need to put in my list. Here's a better example :
static void Main(string[] args)
{
DataType data = new DataType();
List<IMyInterfaceType> myInterfaceType = new List<IMyInterfaceType>();
myInterfaceType.Add(new MyInterfaceImplementationType() { SomeProperty = "property" });
myInterfaceType.Add(new MySecondInterfaceImplementationType() { SomeProperty = "property2" });
data.Rows.Add("key", myInterfaceType);
string serialized = JsonConvert.SerializeObject(data, Formatting.Indented);
DataType deserialized = JsonConvert.DeserializeObject<DataType>(serialized);
}
public class DataType
{
public DataType()
{
Rows = new Dictionary<string, IEnumerable<IMyInterfaceType>>();
}
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto, TypeNameHandling = TypeNameHandling.Auto)]
public Dictionary<string, IEnumerable<IMyInterfaceType>> Rows { get; private set; }
}
public interface IMyInterfaceType
{
string SomeProperty { get; set; }
}
public class MyInterfaceImplementationType : IMyInterfaceType
{
public string SomeProperty { get; set; }
}
public class MySecondInterfaceImplementationType : IMyInterfaceType
{
public string SomeProperty { get; set; }
}
Most helpful comment
Your test case doesn't cover my use case. I have multiple implementations of
IMyInterfaceType
that I need to put in my list. Here's a better example :