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 对象,因此在全局范围内不起作用。
我是 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 对象,因此在全局范围内不起作用。