You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET5 System.Text.Json检测到对象循环抛出JsonException问题咨询

问题根源

该异常抛出在控制器逻辑执行完成后的响应序列化阶段,不在业务代码的try-catch覆盖范围内因此无法被捕获。System.Text.Json默认开启对象循环检测,发现你返回的Person和Schema存在互相引用的循环结构时直接抛出异常,返回的500错误响应缺失标准CORS头,才会被调用端误判为CORS策略问题。

解决方案

方案1:使用DTO切断循环(推荐)

不要直接将业务实体/数据库实体作为接口返回值,单独定义接口专用的DTO(数据传输对象),按需保留字段,移除会导致循环的导航属性即可:

// 接口返回专用的Person DTO
public class PersonDto
{
    public string Name { get; set; }
    // 不需要返回关联的Schema列表时直接删除该属性,从根源切断循环
}

该方案无额外序列化开销,也不会暴露不必要的业务字段,符合接口设计规范。

方案2:全局配置序列化规则处理循环

如果暂时不想调整实体结构,可以直接修改System.Text.Json的全局配置:

.NET 6及以上版本,在Program.cs中添加配置:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 检测到循环引用时将对应字段序列化为null
        options.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles;
        // 如果需要保留引用关系支持反序列化恢复循环结构,可替换为如下配置
        // options.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.Preserve;
    });

.NET Core 3.1/.NET 5版本

低版本System.Text.Json原生不支持循环引用处理,可替换为Newtonsoft.Json(Json.NET)作为序列化器:

  1. 安装NuGet包:Microsoft.AspNetCore.Mvc.NewtonsoftJson
  2. 在Program.cs/Startup.cs中添加配置:
services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    });

方案3:为循环属性添加忽略序列化特性

如果仅需要在特定场景下忽略某一个导航属性,可直接在属性上加[JsonIgnore]特性,注意要和你使用的序列化器对应:

  • 使用System.Text.Json:引用命名空间System.Text.Json.Serialization下的JsonIgnore
  • 使用Newtonsoft.Json:引用命名空间Newtonsoft.Json下的JsonIgnore
public class Person
{
    public string Name { get; set; }
    [JsonIgnore] // 序列化时自动忽略该属性,切断循环
    public List<Schema> Schemas { get; set; }
}

public class Schema
{
    // 也可选择在Schema的Persons属性上加特性,按需选择即可
    public List<Person> Persons { get; set; }
}

内容的提问来源于stack exchange,提问作者Antfolkarn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 10:15:02