繁体   English   中英

Json.net 序列化/反序列化派生类型?

[英]Json.net serialize/deserialize derived types?

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);

这将导致派生类的正确反序列化。 它的一个缺点是它将命名您正在使用的所有对象,因此它将命名您放置对象的列表。

如果您将类型存储在text (在这种情况下应该如此),您可以使用JsonSerializerSettings

请参阅: 如何使用 Newtonsoft JSON.NET 将 JSON 反序列化为 IEnumerable<BaseType>

不过要小心。 使用除TypeNameHandling = TypeNameHandling.None以外的任何内容都可能使您TypeNameHandling = TypeNameHandling.None 安全漏洞

由于这个问题非常流行,如果您想控制类型属性名称及其值,添加该怎么做可能会很有用。

漫长的道路是通过手动检查和设置 type 属性来编写自定义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; }
}

使用这个JsonKnownTypes ,它的使用方式非常相似,只是在 json 中添加了鉴别器:

[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;
}

现在,当您在 json 中序列化对象时,将添加带有"base""derived"值的"$type" ,它将用于反序列化

序列化列表示例:

[
    {"Name":"some name", "$type":"base"},
    {"Name":"some name", "Something":"something", "$type":"derived"}
]

只需在序列化方法中添加 object

 var jsonMessageBody = JsonSerializer.Serialize<object>(model);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM