JSON Newtonsoft C#反序列化不同类型的对象列表

时间:2017-09-05 14:09:21

标签: c# json.net json-deserialization

我需要为现有的报告界面实现远程连接,这需要对数据类进行序列化和反序列化。这是类和接口的简化版本:

    public interface IBase
    {
        string Name { get; }
    }

    public interface IDerived1
    {
        int Value { get; }
    }

    public interface IDerived2
    {
        bool Value { get; }
    }

    public class Base : IBase
    {
        public string Name { get; protected set; }
    }

    public class Derived1 : Base, IDerived1
    {
        public int Value { get; protected set; }
    }

    public class Derived2 : Base, IDerived2
    {
        public bool Value { get; protected set; }
    }

作为输入参数我得

IEnumerable<IBase> reportingData

因此,此集合可能包含“Derived1”和“Derived2”的任意数量和实例组合。然后我将这个集合序列化:

string serialisedReportingData = JsonConvert.SerializeObject( reportingData );

这就是我的例子:

[{“Value”:11,“Name”:“Product Number”},{“Value”:false,“Name”:“Output 1 Enabled”}]

显然,仅使用此数据,反序列化是不可能的,因为单个集合条目的类型不在JSON中。例如,我可以创建JSON的类型部分,或者提供在反序列化期间使用的其他类型集合。

我之前使用过CustomCreationConverter重载来处理

JsonConvert.DeserializeObject<IEnumerable<Ixxx>>( ... );

场景类型,但这仅适用于IEnumerable中的单个接口类型。在上面的示例中,我有两个:IDerived1和IDerived2。

我的问题/问题:

a)我不确定如何编写处理多种接口类型的CustomCreationConverter,我不知道如何将类型输入到此中。

b)我很乐意你就如何实现一个解决方案提出建议,这个解决方案会给我提供与我收到的'IEnumerable reportingData'相同的反序列化输出。

我非常感谢一个可行的代码示例。

非常感谢, 基督教

1 个答案:

答案 0 :(得分:1)

更新:(受dbc的评论启发)

使用类型名称进行反序列化时,应使用SerializationBinder。 请参阅此处查看KnownTypesBinder。 (需要Newtonsoft.Json版本10)

首先,如果要设置属性,则必须使它们if (isset($row["Date"])) { //do something here } 。 然后,您可以使用public进行序列化/反序列化。

JsonSerializerSettings

如果您使用List<IBase> loList = new List<IBase>(); loList.Add(new Base() { Name = "Base" }); loList.Add(new Derived1() { Name = "Derived1", Value = 3 }); loList.Add(new Derived2() { Name = "Derived2", Value = true }); KnownTypesBinder loKnownTypesBinder = new KnownTypesBinder() { KnownTypes = new List<Type> { typeof(Base), typeof(Derived1), typeof(Derived2) } }; IEnumerable<IBase> reportingData = loList.AsEnumerable(); JsonSerializerSettings loJsonSerializerSettings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Objects, SerializationBinder = loKnownTypesBinder }; string lsOut = JsonConvert.SerializeObject(reportingData, loJsonSerializerSettings); reportingData = JsonConvert.DeserializeObject<IEnumerable<IBase>>(lsOut, loJsonSerializerSettings); ,那么类型信息将包含在json字符串中。

JsonSerializerSettings