.NET6 EF Core单表WebAPI报Self referencing loop detected错误
问题根因
这个异常和数据表关联、User模型字段类型没有任何关系,问题出在接口返回值错误:dbContext.Users.Add(newUser)的返回值不是User实体,而是EF Core的EntityEntry<User>跟踪对象。该对象内部持有对DbContext、ChangeTracker等EF Core核心组件的引用,这些组件本身存在双向引用的循环结构,序列化器遍历到这些内部属性时就会触发自引用循环报错。
你之前检索到的多表循环引用是实体类之间的导航属性双向引用导致的,和本次问题场景完全不同,所以调整User字段类型的操作完全没有触碰到问题点。
另外你的代码还存在一个逻辑问题:调用Add方法后没有执行SaveChanges/SaveChangesAsync,新增数据实际不会写入InMemoryDatabase,请求结束后数据就会丢失。
解决方案
推荐方案:返回业务实体而非EF内部跟踪对象
接口不要直接返回Add()方法生成的EntityEntry对象,完成数据持久化后返回实际的User实体即可,修正后的代码:
[HttpPost("Post")] public async Task<IActionResult> Post(User user) { var newUser = new User { Username = user.Username, FacebookId = user.FacebookId, MicrosoftId = user.MicrosoftId, TwitterId = user.TwitterId, GoogleId = user.GoogleId, Email = user.Email, Score = user.Score }; dbContext.Users.Add(newUser); // 持久化数据到内存数据库 await dbContext.SaveChangesAsync(); // 仅返回业务实体,避免序列化EF Core内部对象 return Ok(newUser); }
生产环境更建议定义专用的返回DTO,不要直接返回数据库实体,从根源上避免敏感字段泄露、序列化规则冲突等问题。
兜底方案:配置序列化规则忽略循环引用
如果有特殊场景必须返回包含EF跟踪对象的结构,可以全局配置JSON序列化规则,遇到循环引用时直接忽略而非抛出异常:
- 使用系统默认
System.Text.Json的配置:
// 在Program.cs中配置控制器服务时添加 builder.Services.AddControllers() .AddJsonOptions(opts => { opts.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; });
- 使用
Newtonsoft.Json的配置:
builder.Services.AddControllers() .AddNewtonsoftJson(opts => { opts.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; });
该方案仅能规避报错,返回结果会携带大量EF Core内部无用属性,大幅增加响应体积,非必要不使用。
内容的提问来源于stack exchange,提问作者Woodsoul
相关产品推荐
相关产品推荐

