Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架核心到Json忽略ReferenceLoop-父-子_C#_Json_Serialization_Asp.net Core_Entity Framework Core - Fatal编程技术网

C# 实体框架核心到Json忽略ReferenceLoop-父-子

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; }

我有一个具有父子关系的实体类,在使用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; }
}
但结果是,我从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
因此,在这个种子数据中,我们没有看到A>B>无限循环

在此之后,我们可以使用进行调试,我们应该得到相同的结果。

现在让部门控制器限制错误范围。然后我们启动并运行http repl

让我们来看看实体框架返回了什么

但这会为http repl产生json序列化错误,可能是由于swagger ui json
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;  
        }     
     }