由于 EF Core 会自动修复导航属性,因此最终可以在对象图中使用周期。 例如,加载博客及其相关文章将生成一个引用文章集合的博客对象。 其中每个帖子都将链接回博客。
某些序列化框架不允许此类周期。 例如,如果找到循环,Json.NET 将引发以下异常。
Newtonsoft.Json.JsonSerializationException:针对类型为“MyApplication.Models.Blog”的属性“Blog”检测到的自引用循环。
如果找到循环,System.Text.Json 将引发类似的异常。
System.Text.Json.JsonException:检测到一个可能的对象循环。 这可能是由于循环造成的,或者对象深度大于允许的最大深度为 32。 请考虑在 JsonSerializerOptions 上使用 ReferenceHandler.Preserve 来支持周期。
如果在 ASP.NET Core 中使用 Json.NET,则可以将 Json.NET 配置为忽略它在对象图中找到的周期。 此配置在Startup.cs中的ConfigureServices(...)方法中完成。
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
...
}
如果使用 System.Text.Json,可以按如下所示对其进行配置。
public void ConfigureServices(IServiceCollection services)
{
...
services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
});
...
}
另一种替代方法是忽略导致 JSON 序列化周期的导航属性。 如果使用 Json.NET,则可以使用 [JsonIgnore] 属性修饰其中一个导航属性,该属性指示 Json.NET 在序列化时不遍历该导航属性。 对于 System.Text.Json,可以使用 [JsonIgnore] 命名空间中的 System.Text.Json.Serialization 属性来实现相同的效果。