.net core3 json序列化嵌套对象的问题

两个类

public class CookingMenu
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List MenuItems { get; set; }
}
public class MenuItem
{
    public int Id { get; set; } 
    public int MenuId { get; set; }

    public virtual CookingMenu CookingMenu { get; set; }
}

CookingMenu是主类,MenuItem是子类。CookingMenu包含导航属性MenuItems,MenuItem包含导航属性CookingMenu。
在控制器中,要返回CookingMenu集合的Json对象

public async Task GetCustomerMenus(int customerId)
{
    var menus = context.CookingMenus
        .Include(m => m.MenuItems)
        .Where(m => m.CustomerId == customerId);
    return new JsonResult(new { success = true, menus = await menus.ToListAsync() });
}

如果不加Include方法,代码不会有任何问题,加了Include,会抛出异常:System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32。大意就是检测到不支持的对象循环,循环深度超过最大允许的深度32。

简单分析一下就知道,这实际上是一个循环引用的问题,CookingMenu类引用了MenuItem类,MenuItem中又引用了CookingMenu类,形成循环引用。序列化时就崩溃了。

网上查了一下,说安装Microsoft.AspNetCore.Mvc.NewtonsoftJson包后就可以解决这个问题。于是通过NuGet找到Microsoft.AspNetCore.Mvc.NewtonsoftJson,最新版是3.14,结果安装时报3.14只支持.net core3.1以上版本,而我的项目是.net core 3.0。于是降低版本,安装了Microsoft.AspNetCore.Mvc.NewtonsoftJson 3.0.0,但问题并没有解决,不知道是不是版本问题。
因为异常的命名空间是System.Text.Json,于是查看这个命名空间,发现下面还有个子命名空间Serialization,在这个命名空间中看到了JsonIgnore特性,这个特性可以在序列化忽略被标注的属性。

public class MenuItem
{
    public int Id { get; set; } 
    public int MenuId { get; set; }
	[JsonIgnore]
    public virtual CookingMenu CookingMenu { get; set; }
}

在MenuItem的CookingMenu属性上加上JsonIgnore特性,问题迎刃而解。
不过有个遗留问题,当属性被加上JsonIgnore特性时,我们在Linq查询中即使加上Include方法,该属性也会被忽略。这样我们就无法用Include方法来查看关联数据了。这个问题暂时没找到解决方法,以后再说吧。

你可能感兴趣的:(ASP.NET,Core)