Asp-Net-Core开发笔记:接口返回json对象出现套娃递归问题
前言 看了下推送记录,一个月前,OK,我又变成月更了o(╯□╰)o,这绝对不行![○・`Д´・ ○] 所以今天来更新了 其实不是我懒得更新或者是太忙,其实是最近在写一篇很长的博客,一直没写完( Ĭ ^ Ĭ ) 好吧,先进入正题…… 有一个关于WebApi序列化的问题,跟设计有关,但在涉及到关联字段的时候经常会遇到。 实体类 先看看实体类定义,限于篇幅,只保留几个关键字段。 public class
目录7 个章节
前言
看了下推送记录,一个月前,OK,我又变成月更了o(╯□╰)o,这绝对不行![○・`Д´・ ○]
所以今天来更新了
其实不是我懒得更新或者是太忙,其实是最近在写一篇很长的博客,一直没写完( Ĭ ^ Ĭ )
好吧,先进入正题……
有一个关于WebApi序列化的问题,跟设计有关,但在涉及到关联字段的时候经常会遇到。
实体类
先看看实体类定义,限于篇幅,只保留几个关键字段。
public class CrawlTask : EntityBase {
/// <summary>
/// 爬虫名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 创建这个爬虫的用户
/// </summary>
public User User { get; set; }
/// <summary>
/// 用户ID
/// </summary>
public string? UserId { get; set; }
}
用户实体类:
public class User : EntityBase {
/// <summary>
/// 用户名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 用户创建的爬虫
/// </summary>
public List<CrawlTask> CrawlTasks { get; set; }
}
接口
然后接口这样写:
/// <summary>
/// 获取用户创建的全部爬虫
/// </summary>
/// <returns></returns>
[HttpGet]
public ActionResult<List<CrawlTask>> GetAll() {
var user = _authService.GetUser(User.Identity?.Name);
return user.CrawlTasks;
}
然后请求这个接口,我们期望的数据是:
[
{
"name": "爬虫名称",
"user": {
"name": "用户名"
},
"userId": "0f3d4b2f-3b4e-4d08-8f4c-0009a316f041",
"id": "4d52d83b-f3ec-47c6-ab26-e241c09c14d1"
}
]
报错
但事实是直接报错:
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 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.
Path: $.User.CrawlTasks.User.CrawlTasks.User.CrawlTasks.User.CrawlTasks.User.CrawlTasks.User.CrawlTasks.User.CrawlTasks.User.CrawlTasks.User.CrawlTasks.User.CrawlTasks.Name.
很明显,返回的对象套娃递归了。
注意那个Path:$.User.CrawlTasks.User.CrawlTasks.User.Crawl... ,我们上面期望的json数据是:
{
"name": "test crawl123",
"user": {
"name": "string"
},
"userId": "0f3d4b2f-3b4e-4d08-8f4c-0009a316f041",
"id": "4d52d83b-f3ec-47c6-ab26-e241c09c14d1"
}
即Crawl对象下的User只有Name属性,不要把CrawlTasks列表也显示出来,但程序它不知道啊,User里有CrawlTasks,然后CrawlTasks里面又有User,这就陷入一个套娃递归了……
初步解决
很明显,这根设计和数据获取方式有问题,可以通过换个查询方式来避免,比如:
[HttpGet]
public ActionResult<List<CrawlTask>> GetAll() {
return _crawlRepo
.Where(a => a.UserId == User.Identity.Name)
.ToList();
}
因为这里没有请求Crawl的导航属性User,所以不会读取User对象的信息,出现的结果是这样:
[
{
"name": "test crawl123",
"user": null,
"userId": "0f3d4b2f-3b4e-4d08-8f4c-0009a316f041",
"id": "4d52d83b-f3ec-47c6-ab26-e241c09c14d1"
}
]
可以看到User对象的值是null,对于接口来说已经够用了,毕竟这是获取当前用户的所有爬虫,所有爬虫的user属性都是同一个,没必要重复啦。
不过即使把User对象加上也是完全没问题的,这里改一下接口看一下效果:
[HttpGet]
public ActionResult<List<CrawlTask>> GetAll() {
return _crawlRepo.Select
.Where(a => a.UserId == User.Identity.Name)
.Include(a => a.User) // 添加了这行代码,请求关联对象
.ToList();
}
返回的结果:
[
{
"name": "test crawl123",
"user": {
"name": "string",
"crawlTasks": null,
"id": "0f3d4b2f-3b4e-4d08-8f4c-0009a316f041"
},
"userId": "0f3d4b2f-3b4e-4d08-8f4c-0009a316f041",
"id": "4d52d83b-f3ec-47c6-ab26-e241c09c14d1"
}
]
可以看到,返回的Crawl对象中,User对象里的crawlTasks属性是空的,因为我们前面加的那行代码:.Include(a => a.User),FreeSQL还支持进一步查询User的导航属性crawlTasks,但需要置顶Include的then参数,配置套娃查询……
继续!
那有没有什么办法是不改动接口代码的情况下,解决接口套娃的问题?
答案肯定有啦
这就要用NewtonsoftJson了~
首先安装Microsoft.AspNetCore.Mvc.NewtonsoftJson这个nuget包
然后在服务配置里面添加代码
services.AddControllersWithViews()
.AddNewtonsoftJson(options => {
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
然后再请求接口,返回的结果就跟上面的一样啦~
会导致套娃递归的属性直接变成null~
PS:这个代码的作用就是把WebApi默认的json序列化器从System.Text.Json改成NewtonsoftJson,并且配置处理套娃递归的方式为忽略~
参考文档
_EOF_
Asp-Net-Core开发笔记:接口返回json对象出现套娃递归问题
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
Asp-Net-Core开发笔记:使用NPM和gulp管理前端静态文件
前言 本文介绍的是AspNetCore的MVC项目,WebApi+独立前端这种前后端分离的项目就不需要多此一举了~默认前端小伙伴是懂得使用前端工具链的。 为啥要用MVC这种服务端渲染技术呢? 简单项目不需要强行分离增加复杂度(如:我正在开发的博客项目) 后端渲染利于SEO,对博客网站友好 OK,虽然MVC的技术老了点,但依然可以结合现代前端工具链来提高效率 本文的食用需要先安装好Node.js环境
2022-02-17 · Asp-Net-Core开发笔记 · 约 1 分钟
Asp-Net-Core开发笔记:给SwaggerUI加上登录保护功能
既要在项目发布后访问 SwaggerUI ,又要保证一定的安全性,本文提供的思路或许是一种比较简单又有效的解决方案。
2024-05-21 · Asp-Net-Core开发笔记 · 约 1 分钟
Asp-Net-Core开发笔记:使用alpine镜像并加入健康检查
用alpine镜像?不过是把体积砍半,健康检查加个路径就完事。wget自带,何必装curl,真是多余。发布选linux-musl-x64,不然别想跑。
2024-04-19 · Asp-Net-Core开发笔记 · 约 1 分钟
Asp-Net-Core开发笔记:使用ActionFilterAttribute实现非侵入式的参数校验
用ActionFilterAttribute搞非侵入校验,省得重复写代码。支持Query、Body、Route、Header,HttpContext共享数据,但OAuth2.0边学边做,项目乱糟糟,功能凑合。
2024-05-17 · Asp-Net-Core开发笔记 · 约 1 分钟
讨论
共 0 条加载评论中…