Entity Framework Core to Json Ignore ReferenceLoop - Parent Child

asp.net-core c# entity-framework-core json serialization

Question

I having entity class with parent-child relationship that having problem serializing to json using newtonsoft json.net

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

While i'm expecting a json format such as this.

[
  {
    "departmentId": 1,   
    "title":        "Finance",
    "children": [
      {
        "departmentId": 2,        
        "title":        "Accounting",
        "children": [
          {
            "departmentId": 3,            
            "title":        "Payable"
          }
        ]
      }
    ]
  }
]

But the result i get this Stackoverflow Exception from http-repl Stackoverflow exception

I trying using Ignore ReferenceLooping, this doesn't solve the stackoverflow problem i have

services.AddMvc()
    .AddJsonOptions(options => {
       options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    })

Here is the Controller, if you are asking;

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

I have tried Data Transfer Object (DTO) still not working.

Update 29 Dec 2018

Let set this up correctly, you can clone base project at https://github.com/wangkanai/Organization/tree/base. Then you can add the database in the following path src\Organization.WebApi

dotnet ef migrations add init
dotnet ef database update

This will give you at seed data for Department with following data

Department Seed Data

From the seed Data, the maximum child we will have only 3 level deep and no circle release as infinite loop.

  • A > B > C

So we don't see A > B > A infinite loop here in this seed data.

After this we can doing debug using dotnet-httprepl and we should the same results. StackOverFlow

Now lets comment out all methods in the department controller to limited the error scope. Then we get the http-repl up and running.

https://github.com/wangkanai/Organization/tree/bases/refactor

So let just enable get all departments and see what entity framework returns;

Department with no parent as root departments

But this produce json serialization error for http-repl, maybe from swagger ui json http://localhost:56739/swagger/v1/swagger.json

Stackoverflow by enabling get all

Lets add \[JsonIgnore\] to the Site & Parent then rerun the 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; }
}

Still its produce the same error

Evening ignore the parent

So now let Ignore all relationship to serialize json to see if we can get all departments. But this produce departments without its children, which is not we are expecting the correct results.

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

get all departments but without the children

1
2
12/19/2018 12:56:52 PM

Popular Answer

I don't think that you need to convert DTO just to get json format as you have got EF Code first model which I can see

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

You can directly return json output as following way from your action controller.

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

I have not tested on IDE though let me know if any issue on code.

0
12/18/2018 5:01:52 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow