Ядро Entity Framework для Json Игнорировать ReferenceLoop - Родительский дочерний элемент - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть класс сущности с родительскими и дочерними отношениями, который имеет проблемы с сериализацией в json с использованием 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; }
}

Хотя я ожидаю такой формат json, как этот.

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

Но в результате я получаю это исключение Stackoverflow из http-repl Stackoverflow exception

Я пытаюсь использовать Ignore ReferenceLooping, это не решает проблему переполнения стека у меня

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), все еще не работает.

Обновление 29 декабря 2018

Позвольте установить это правильно,Вы можете клонировать базовый проект на https://github.com/wangkanai/Organization/tree/base. Затем вы можете добавить базу данных по следующему пути src\Organization.WebApi

dotnet ef migrations add init
dotnet ef database update

Это даст вам начальные данные для Отдела со следующими данными

Department Seed Data

Из начальных данных, максимаМой ребенок, у нас будет только 3 уровня глубины, и круг не будет освобожден как бесконечный цикл.

  • A> B> C

Так что мы не видим A> B>Здесь в этих начальных данных бесконечный цикл.

После этого мы можем выполнить отладку, используя dotnet-httprepl , и мы должны получить те же результаты.StackOverFlow

Теперь давайте закомментируем все методы в контроллере отдела, чтобы ограничить область ошибок.Затем мы запустим http-repl и запустим его.

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

Так что давайте просто включим все отделы и посмотрим, какая структура сущностейвозвращает;

Department with no parent as root departments

Но это приводит к ошибке сериализации json для http-repl, возможно, из swagger ui json http://localhost:56739/swagger/v1/swagger.json

Stackoverflow by enabling get all

Давайте добавим \[JsonIgnore\] к сайту и родительскому элементу , затем повторно запустим 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; }
}

Тем не менее выдает ту же ошибку

Evening ignore the parent

Итак, теперь позволяет игнорировать все отношения для сериализации 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; }
}

get all departments but without the children

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Я не думаю, что вам нужно конвертировать 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, хотя дайте мне знать, если какие-либо проблемы с кодом.

0 голосов
/ 18 декабря 2018

Я удивлен, что выдает это исключение, поскольку обычно 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; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...