由于 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(...) 方法完成的。
C#
复制
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
...
}
如果使用 System.Text.Json,可按如下所示对其进行配置。
C#
复制
public void ConfigureServices(IServiceCollection services)
{
...
services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
});
...
}
另一种替代方法是忽略导致 JSON 序列化循环的导航属性。 如果使用 Json.NET,可以使用 [JsonIgnore] 特性修饰其中一个导航属性,该特性指示 Json.NET 在序列化时不遍历该导航属性。 对于 System.Text.Json,可以使用 System.Text.Json.Serialization 命名空间中的 [JsonIgnore] 特性来实现相同的效果。