json.net(newtonsoft)
我正在查阅文档,但找不到关于此事的任何信息或最佳方法。
public class Base
{
public string Name;
}
public class Derived : Base
{
public string Something;
}
JsonConvert.Deserialize<List<Base>>(text);
现在我有一个序列化列表中的派生对象。如何反序列化该列表并获取回派生类型?
json.net(newtonsoft)
我正在查阅文档,但找不到关于此事的任何信息或最佳方法。
public class Base
{
public string Name;
}
public class Derived : Base
{
public string Something;
}
JsonConvert.Deserialize<List<Base>>(text);
现在我有一个序列化列表中的派生对象。如何反序列化该列表并获取回派生类型?
您需要启用类型名称处理,并将其作为设置参数传递给序列化和反序列化操作。
Base object1 = new Base() { Name = "Object1" };
Derived object2 = new Derived() { Something = "Some other thing" };
List<Base> inheritanceList = new List<Base>() { object1, object2 };
JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
string Serialized = JsonConvert.SerializeObject(inheritanceList, settings);
List<Base> deserializedList = JsonConvert.DeserializeObject<List<Base>>(Serialized, settings);
这将导致派生类的正确反序列化。它的缺点是它会为您使用的所有对象命名,因此它将为您放置对象的列表命名。
TypeNameHandling.Auto
也可以实现此功能,并且更好,因为它在字段/属性类型与实例类型匹配时不会写入实例类型名称,这通常是大多数字段/属性的情况。 - Roman StarkovTypeNameHandling = TypeNameHandling.Auto
- 这将仅在声明的类型(例如 Base
)与实例类型(例如 Derived
)不匹配的情况下,为实例添加 $type
属性。这样,它不会像 TypeNameHandling.All
那样让您的 JSON 变得臃肿。 - AJ RichardsonSystem.Text.Json.Serialization
完成相同操作的方法:https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-polymorphism - ryanwebjackson鉴于这个问题非常受欢迎,如果您想控制类型属性名称及其值,添加以下内容可能会很有用。
一种冗长的方式是编写自定义JsonConverter
来通过手动检查和设置类型属性来处理(反)序列化。
更简单的方法是使用JsonSubTypes,它通过属性处理所有样板文件:
[JsonConverter(typeof(JsonSubtypes), "Sound")]
[JsonSubtypes.KnownSubType(typeof(Dog), "Bark")]
[JsonSubtypes.KnownSubType(typeof(Cat), "Meow")]
public class Animal
{
public virtual string Sound { get; }
public string Color { get; set; }
}
public class Dog : Animal
{
public override string Sound { get; } = "Bark";
public string Breed { get; set; }
}
public class Cat : Animal
{
public override string Sound { get; } = "Meow";
public bool Declawed { get; set; }
}
JsonSubtypes
定义在哪里?我使用的是 Newtonsoft.Json 版本 12.0.0.0,并且没有提到那篇文章中的 JsonSubtypes
、JsonSubTypes
或 JsonSubtypesConverterBuilder
。 - Matt Arnold[JsonConverter(typeof(JsonKnownTypeConverter<BaseClass>))]
[JsonKnownType(typeof(Base), "base")]
[JsonKnownType(typeof(Derived), "derived")]
public class Base
{
public string Name;
}
public class Derived : Base
{
public string Something;
}
[
{"Name":"some name", "$type":"base"},
{"Name":"some name", "Something":"something", "$type":"derived"}
]
只需在 Serialize 方法中添加对象即可
var jsonMessageBody = JsonSerializer.Serialize<object>(model);