gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 02:03:02 25 4
gpt4 key购买 nike

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

    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 内的单个接口(interface)类型。在上面的示例中,我有两个:IDerived1 和 IDerived2。

我的问题/问题:

a)我不确定如何编写处理多个接口(interface)类型的 CustomCreationConverter,我不知道如何将类型放入其中。

b)我希望您就如何实现一个解决方案提出建议,该解决方案将为我提供与我作为输入收到的“IEnumerable reportingData”相同的反序列化输出。

如果可能,我将非常感谢一个工作代码示例。

提前谢谢了,
基督教

最佳答案

更新:(灵感来自 dbc 的评论)

您应该使用 SerializationBinder使用类型名称反序列化时。
见这里KnownTypesBinder . (需要 Newtonsoft.Json 版本大于 10)

首先,如果你想设置你的属性,你必须将它们设为 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);

如果您使用 JsonSerializerSettings这样,类型信息将包含在 json 字符串中。
[{
"$type": "Base",
"Name": "Base"
}, {
"$type": "Derived1",
"Value": 3,
"Name": "Derived1"
}, {
"$type": "Derived2",
"Value": true,
"Name": "Derived2"
}
]

关于c# - JSON Newtonsoft C# 反序列化不同类型对象的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46057081/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com