dotnet 6 最小 API 循环序列化

dotnet 6 minimal API circular serialization

我是 dotnet 的新手,正在试用 dotnet 6 minimal API。我有两个模型:

namespace Linker.Models
{
    class Link : BaseEntity
    {
        [MaxLength(2048)]
        public string Url { get; set;} = default!;
        [MaxLength(65536)]
        public string? Description { get; set; }
        [Required]
        public User Owner { get; set; } = default!;
        [Required]
        public Space Space { get; set; } = default!;
    }
}

并且:

namespace Linker.Models
{
    class Space : BaseEntity
    {
        public string Name { get; set; } = default!;
        public string Code { get; set; } = default!;
        public User Owner { get; set; } = default!;
        public List<Link> Links { get; set; } = new List<Link>();
    }
}

现在,当我尝试序列化 Space 模型时,出现错误 System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 64.(有道理,因为 Path: $.Links.Space.Links.Space.Links.Space.Links.Space.Links.Space.Links...)。是否可以防止 dotnet 序列化这么深的对象?我什至不需要 dotnet 来尝试序列化如此深的关系

您可以在JsonSerializerOptions中设置ReferenceHandler.Preserve。这些文档 How to preserve references and handle or ignore circular references in System.Text.Json 进一步讨论。

对于手动 serialization/deserialization 将选项传递给 JsonSerializer:

JsonSerializerOptions options = new()
{
    ReferenceHandler = ReferenceHandler.Preserve
};
string serialized = JsonSerializer.Serialize(model, options);

或者以最小的方式全局配置 API:

using Microsoft.AspNetCore.Http.Json;

var builder = WebApplication.CreateBuilder(args);

// Set the JSON serializer options
builder.Services.Configure<JsonOptions>(options =>
{
    options.SerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
});

您可以 ignore the circular references 而不是使用 ReferenceHandler.IgnoreCycles 来处理它们。序列化程序会将循环引用设置为 null,因此使用此方法可能会丢失数据。

全局配置被忽略的原因是使用了错误的 JsonOptions。以下应该有效:

builder.Services.Configure(选项 =>

... 其余代码

我对 JsonOptions 的默认设置是 Microsoft.AspNetCore.Mvc.JsonOptions,这不是要更改的正确 JsonOptions 对象,因此在全局范围内不起作用。