C# 实体框架核心到Json忽略ReferenceLoop-父-子
我有一个具有父子关系的实体类,在使用newtonsoft json.net序列化为json时遇到问题C# 实体框架核心到Json忽略ReferenceLoop-父-子,c#,json,serialization,asp.net-core,entity-framework-core,C#,Json,Serialization,Asp.net Core,Entity Framework Core,我有一个具有父子关系的实体类,在使用newtonsoft json.net序列化为json时遇到问题 public class Department { [Key] public int DepartmentId { get; set; } public int? ParentId { get; set; } public Department Parent { get; set; }
public class Department
{
[Key]
public int DepartmentId { get; set; }
public int? ParentId { get; set; }
public Department Parent { get; set; }
public ICollection<Department> Children { get; set; }
public string Title { get; set; }
}
但结果是,我从http repl获得了这个Stackoverflow异常
我尝试使用Ignore ReferenceLooping,但这并不能解决我遇到的stackoverflow问题
services.AddMvc()
.AddJsonOptions(options => {
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
})
这是控制器,如果你问的话
//GET: api/Department
[HttpGet]
public async Task<ActionResult<IEnumerable<Department>>> GetDepartments()
{
var result = await _context.Departments
.Include(department => department.Children)
.Where(department => department.ParentId == null)
.ToListAsync();
return Ok(result);
}
这将为您提供具有以下数据的部门的at seed数据
从种子数据来看,最大子级只有3级深度,没有无限循环的循环释放
- A>B>C
http://localhost:56739/swagger/v1/swagger.json
然后重新运行http repl
public class Department
{
[Key]
public int DepartmentId { get; set; }
[JsonIgnore]
public int SiteId { get; set; }
[JsonIgnore]
public Site Site { get; set; }
[JsonIgnore]
public int? ParentId { get; set; }
[JsonIgnore]
public Department Parent { get; set; }
public ICollection<Department> Children { get; set; }
public string Title { get; set; }
}
公共课部
{
[关键]
public int DepartmentId{get;set;}
[JsonIgnore]
public int SiteId{get;set;}
[JsonIgnore]
公共站点站点{get;set;}
[JsonIgnore]
public int?ParentId{get;set;}
[JsonIgnore]
公共部门父项{get;set;}
公共ICollection子项{get;set;}
公共字符串标题{get;set;}
}
它仍然会产生同样的错误
现在我们来序列化json,看看是否可以得到所有部门。但这产生了没有子系统的部门,这不是我们所期望的正确结果
public class Department
{
[Key]
public int DepartmentId { get; set; }
[JsonIgnore]
public int SiteId { get; set; }
[JsonIgnore]
public Site Site { get; set; }
[JsonIgnore]
public int? ParentId { get; set; }
[JsonIgnore]
public Department Parent { get; set; }
[JsonIgnore]
public ICollection<Department> Children { get; set; }
public string Title { get; set; }
}
公共课部
{
[关键]
public int DepartmentId{get;set;}
[JsonIgnore]
public int SiteId{get;set;}
[JsonIgnore]
公共站点站点{get;set;}
[JsonIgnore]
public int?ParentId{get;set;}
[JsonIgnore]
公共部门父项{get;set;}
[JsonIgnore]
公共ICollection子项{get;set;}
公共字符串标题{get;set;}
}
我很惊讶它会抛出这个异常,因为通常Json.NET会在堆栈溢出发生之前捕获循环引用。但仍然有可能是循环引用扼杀了它。(它试图序列化
父项
,然后查看其中的子项
,然后查看每个子项的父项
,等等。)
您可以修改模型,让序列化忽略父级:
public class Department
{
[Key]
public int DepartmentId { get; set; }
public int? ParentId { get; set; }
[JsonIgnore]
public Department Parent { get; set; }
public ICollection<Department> Children { get; set; }
public string Title { get; set; }
}
公共课部
{
[关键]
public int DepartmentId{get;set;}
public int?ParentId{get;set;}
[JsonIgnore]
公共部门父项{get;set;}
公共ICollection子项{get;set;}
公共字符串标题{get;set;}
}
我认为您不需要将DTO转换为json格式,因为我可以看到EF code first模型
public class Department
{
[Key]
public int DepartmentId { get; set; }
public int? ParentId { get; set; }
public Department Parent { get; set; }
public ICollection<Department> Children { get; set; }
public string Title { get; set; }
}
公共课部
{
[关键]
public int DepartmentId{get;set;}
public int?ParentId{get;set;}
公共部门父项{get;set;}
公共ICollection子项{get;set;}
公共字符串标题{get;set;}
}
您可以按照以下方式从动作控制器直接返回json输出
public class JsonDemoController : Controller
{
#region ActionControllers
/// <summary>
/// Get department data in Json Format
/// </summary>
/// <returns></returns>
public JsonResult GetDepartmentJsonData()
{
var departments= GetDepartments();
return Json(departments, JsonRequestBehavior.AllowGet);
}
private List<Department> GetDepartments()
{
var departmentList = new List<Department>
{
new Department
{
DepartmentId = 1,
Title = "Finance",
Children = childrenCollection
}
};
return departmentList;
}
}
公共类JsonDemoController:Controller
{
#区域操作控制器
///
///获取Json格式的部门数据
///
///
公共JsonResult GetDepartmentJsonData()
{
var departments=GetDepartments();
返回Json(departments,JsonRequestBehavior.AllowGet);
}
私人部门名单
{
var部门列表=新列表
{
新部门
{
部门ID=1,
Title=“金融”,
childrenCollection=childrenCollection
}
};
返回部门列表;
}
}
我还没有在IDE上测试过,但是如果代码有任何问题,请告诉我 请出示您的控制器方法代码!你用过AutoMapper吗?@TanvirArjel看一下@Alitoshmalani是的,我试过了AutoMapper@SarinNaWangkanai请检查我的答案,让我知道它是否有效!如果没有,请告诉我问题所在!是的,我试过在
父项上添加AutoMapper[JsonIgnore]
没有帮助,如果我在子项上添加[JsonIgnore]
则不会生成子项。如果忽略子项
使其完整(但没有子项),则意味着在子项中有一个循环引用(一个部门有一个孩子,同时也是它自己的家长)。它甚至可能有几个层次的深度,比如:a->B->C->a。这将导致它无限循环。在我尝试使用AutoMapper之前,我已经尝试过手动创建一个映射器。现在,我头上的AutoMapper已经旋转了几天了。
public class Department
{
[Key]
public int DepartmentId { get; set; }
public int? ParentId { get; set; }
public Department Parent { get; set; }
public ICollection<Department> Children { get; set; }
public string Title { get; set; }
}
public class JsonDemoController : Controller
{
#region ActionControllers
/// <summary>
/// Get department data in Json Format
/// </summary>
/// <returns></returns>
public JsonResult GetDepartmentJsonData()
{
var departments= GetDepartments();
return Json(departments, JsonRequestBehavior.AllowGet);
}
private List<Department> GetDepartments()
{
var departmentList = new List<Department>
{
new Department
{
DepartmentId = 1,
Title = "Finance",
Children = childrenCollection
}
};
return departmentList;
}
}