現在のビジネスシナリオとして、雇員クラスがあり、その中に管理者という属性があり、それも同じ雇員クラスのタイプです。通常の雇員の管理者はマネージャー、マネージャーの管理者はCEOであり、CEOの管理者は空か自分自身を管理しています。空は正常ですが、もしCEOの管理者が自分自身の場合、.NET9では以下のように実現します:
using System.Text.Json;
var ceo = new Employee { NO = 1, Name = "CEO" };
ceo.Manager = ceo; // ここでエラーが発生
Console.WriteLine(JsonSerializer.Serialize(ceo));
Console.WriteLine("---------------");
var manager = new Employee { NO = 2, Name = "Manager" };
manager.Manager = ceo;
Console.WriteLine(JsonSerializer.Serialize(manager));
Console.WriteLine("---------------");
var employee = new Employee { NO = 3, Name = "Employee" };
employee.Manager = manager;
Console.WriteLine(JsonSerializer.Serialize(employee));
class Employee
{
public int NO { get; set; }
public string? Name { get; set; }
public Employee? Manager { get; set; }
}
実行すると、循環参照の例外が発生します:
源生成器を用いてJSONシリアル化を行う場合、生成されるコンテキストは循環参照でシリアル化やデシリアル化を行う際に例外をスローします。今では、JsonSourceGenerationOptionsAttribute
においてReferenceHandler
を指定することでこの動作をカスタマイズすることができます。以下は、JsonKnownReferenceHandler.Preserve
を使用した例です:
using System.Text.Json;
using System.Text.Json.Serialization;
var ceo = new Employee { NO = 1, Name = "CEO" };
ceo.Manager = ceo;
Console.WriteLine(JsonSerializer.Serialize(ceo, ContextWithPreserveReference.Default.Employee));
Console.WriteLine("---------------");
var manager = new Employee { NO = 2, Name = "Manager" };
manager.Manager = ceo;
Console.WriteLine(JsonSerializer.Serialize(manager, ContextWithPreserveReference.Default.Employee));
Console.WriteLine("---------------");
var employee = new Employee { NO = 3, Name = "Employee" };
employee.Manager = manager;
Console.WriteLine(JsonSerializer.Serialize(employee, ContextWithPreserveReference.Default.Employee));
Console.ReadLine();
[JsonSourceGenerationOptions(ReferenceHandler = JsonKnownReferenceHandler.Preserve)]
[JsonSerializable(typeof(Employee))]
internal partial class ContextWithPreserveReference : JsonSerializerContext
{
}
class Employee
{
public int NO { get; set; }
public string? Name { get; set; }
public Employee? Manager { get; set; }
}
実行結果は以下の通りです:
(Translated by GPT)
元のリンク:https://mp.weixin.qq.com/s/GLdh4ZHzNVz3xqeEenqG9g?token=1135395277&lang=zh_CN&wt.mc_id=MVP_325642