繁体   English   中英

使用JsonDerivedType属性序列化和反序列化Polymorphic对象 .NET 7

[英]Using JsonDerivedType attribute to serialize and deserialize Polymorphic objects in .NET 7

JSON.NET(由 Newtonsoft 提供)对复杂对象的序列化和反序列化有很好的支持。

我对使用System.Text.Json而不是 JSON.NET 很好奇,但我无法在 inte.net 上找到好的教程。

.NET 7 预览版支持反序列化多态对象。 这是使用 .NET 7 预览和 C# 11 的示例:

// _To run it you will need net7 preview and c# 11_

using System.Text.Json.Serialization;

var testPolymorphism = new TestPolymorphysm()
{
    Animals = new List<Animal>()
    {
        new Fish() {
             Id = "fish1",
             Name = "GoldFish",
             Action = new ActionSwim() { DistanceSwam = 10 }
        },
        new Dog() {
             Id = "dog1",
             Name = "Tom",
             Action = new ActionRun() { DistanceRan = 50  }
        }
    }
};

// serialize
var jsonSerialized = System.Text.Json.JsonSerializer.Serialize(testPolymorphism);
Console.WriteLine(jsonSerialized);

// deserialize
var clonePolymorphysm = System.Text.Json.JsonSerializer.Deserialize<TestPolymorphysm>(jsonSerialized);
Console.WriteLine(clonePolymorphysm);


// === MODELS ===

class TestPolymorphysm
{
    public List<Animal> Animals { get; set; } = new();
}

[JsonDerivedType(derivedType: typeof(Dog), typeDiscriminator: "foo1")]
[JsonDerivedType(derivedType: typeof(Fish), typeDiscriminator: "foo2")]
abstract class Animal
{
    public required string Id { get; set; }
    public required string Name { get; set; }
}

class Dog : Animal
{
    public required IAction Action { get; set; }
    public AnimalType ExtensionType => AnimalType.Dog;
}

class Fish : Animal
{
    public required IAction Action { get; set; }
    public AnimalType ExtensionType => AnimalType.Fish;
}

[JsonDerivedType(derivedType: typeof(ActionSwim), typeDiscriminator: "foo3")]
[JsonDerivedType(derivedType: typeof(ActionRun), typeDiscriminator: "foo4")]
interface IAction { }
class ActionSwim : IAction
{
    public required int DistanceSwam { get; set; }
}

class ActionRun : IAction
{
    public required int DistanceRan { get; set; }
}

public enum AnimalType
{
    Fish,
    Dog
}

无论如何,这段代码由于JsonDerivedType属性而起作用,但我不确定它为什么起作用。 为什么如果我删除 typeDiscriminators foo1、foo2、foo3 和 foo4 它不起作用? 我想确保我在使用它之前了解它是如何工作的。

抱歉,我没有注意序列化的对象。 它包含: "$type": "foo1", "$type": "foo2",等。

这就是反序列化器知道如何反序列化对象的原因。

该过程在文档中有描述: https://learn.microsoft.com/en-us/do.net/standard/serialization/system-text-json/polymorphism?pivots=do.net-7-0#polymorphic-类型鉴别器

要启用多态反序列化,您必须为派生的 class 指定类型鉴别器...使用添加的元数据,特别是类型鉴别器,序列化程序可以序列化和反序列化有效负载...序列化将发出 JSON 以及类型鉴别器元数据

本质上, JsonDerivedTypeAttribute标识支持的派生类型并将类型鉴别器$type添加为 JSON 元数据,这反过来指示序列化程序。

暂无
暂无

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

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