我的实体类具有父子关系,但是在使用newtonsoft json.net序列化到json时遇到问题
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; }
}
虽然我期望这样的json格式。
[
{
"departmentId": 1,
"title": "Finance",
"children": [
{
"departmentId": 2,
"title": "Accounting",
"children": [
{
"departmentId": 3,
"title": "Payable"
}
]
}
]
}
]
但是结果我从http-repl得到了这个Stackoverflow异常
我尝试使用忽略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);
}
我尝试过数据传输对象(DTO)仍然无法正常工作。
请正确设置此设置,您可以在https://github.com/wangkanai/Organization/tree/base上克隆基础项目。然后,您可以在以下路径src\Organization.WebApi
dotnet ef migrations add init
dotnet ef database update
这将为您提供Department的种子数据以及以下数据
从种子数据来看,最大子级只有3个层级的深度,并且没有循环释放为无限循环。
因此我们在此种子数据中看不到A> B>无限循环。
此后,我们可以使用dotnet-httprepl进行调试,结果应该相同。
现在,让部门控制器中的comment out all methods限制错误范围。然后,我们启动并运行了http-repl。
因此,只需enable get all departments,看看实体框架会返回什么;
但这会为http-repl产生json序列化错误,可能是由于swagger ui json http://localhost:56739/swagger/v1/swagger.json
Lets add \[JsonIgnore\]
to the Site & Parent,然后重新运行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; }
}
仍然产生相同的错误
所以现在let Ignore all relationship来序列化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; }
}
答案 0 :(得分:0)
我很惊讶它抛出 异常,因为通常Json.NET在StackOverflow发生之前会捕获循环引用。但是仍然有可能是循环引用将其杀死。 (它正在尝试序列化Parent
,然后查看其中的Children
,然后查看其中每个的Parent
,依此类推。)
您可以修改模型以告知序列化忽略Parent
:
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; }
}
答案 1 :(得分:0)
我认为您无需转换DTO即可获取json格式,因为您拥有EF Code的第一个模型,我可以看到
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; }
}
您可以按照以下方式从操作控制器直接返回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;
}
}
我没有在IDE上进行测试,但是让我知道代码是否存在问题。