Search code examples
asp.net-mvcentity-frameworkasp.net-coreef-code-firstasp.net-core-3.1

.net core 3.0 entity infinite loop


I have some issues with .net core entity while fetching data.

this is my controller code

_context.Hierarchies
    .Include(i => i.Children)
    .AsEnumerable()
    .Where(x => x.Parent == null)
    .ToList();

and this is my Model Class

   public class Hierarchy
    {
        public Hierarchy()
        {
            CreatedDate = DateTime.UtcNow;
            Children = new List<Hierarchy>();
        }
        public long Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public User CreatedBy { get; set; }
        public DateTime CreatedDate { get; set; }
        public Organization Organization { get; set; }
        public List<Task> Tasks{ get; set; }
        public Hierarchy Parent { get; set; }
        public long? ParentId { get; set; }
        public List<Hierarchy> Children { get; set; }
    }

and this is my db context model builder

 modelBuilder.Entity<Hierarchy>(hierarchy => {
                hierarchy.HasMany(c => c.Children)
                .WithOne(c => c.Parent)
                .HasForeignKey(c => c.ParentId);
            });

When call my api result is

[
    {
        "id": 16,
        "name": "category1",
        "description": null,
        "createdBy": {
            "id": 2,
            "email": "test@test.com",
            "passwordHash": "IR4uM8YiGpzevGjNYQHfFgFBkHqTqGy3rgCsA8d9LNZAmTItvy2l3MXSnPcXQD7QldV3X5GA/CKSF4mPCFkAYg==",
            "passwordSalt": "XWzpfAf8IA7wpgY+gtVHiGPxTX4avvn38VY7MFspMhAfPUwL1a9ctuSQcEPlRJKqfK/3yZRtPWUlMQV7XH0JHRd4bKFvH/NKpSr4v46vOlgdQWAZDH1dklmqPtCmYK/Rq8SC/qcKfrmQLbJewBJ7B1Fse33ohAXp29+0K1c4YsE=",
            "name": null,
            "avatar": null,
            "address": null,
            "aboutMe": null,
            "company": null,
            "job": null,
            "city": null,
            "country": null,
            "birthday": "0001-01-01T00:00:00",
            "createdDate": "2020-04-08T02:38:40.288739",
            "userOrganizations": null,
            "ownerTasks": null,
            "assignedTasks": null,
            "assigneeTasks": null,
            "currentOrganization": {
                "id": 2,
                "name": "Default",
                "description": "",
                "createdDate": "2020-04-07T23:38:40.459297",
                "userOrganizations": [],
                "hierarchies": [
                    {
                        "id": 17,
                        "name": "category2",
                        "description": null,
                        "createdDate": "2020-04-08T02:09:46.1474742Z",
                        "tasks": [],
                        "parentId": 16,
                        "children": []
                    }
                ]
            }
        },
        "createdDate": "2020-04-08T02:09:34.54658",
        "organization": {
            "id": 2,
            "name": "Default",
            "description": "",
            "createdDate": "2020-04-07T23:38:40.459297",
            "userOrganizations": [],
            "hierarchies": [
                {
                    "id": 17,
                    "name": "category2",
                    "description": null,
                    "createdBy": {
                        "id": 2,
                        "email": "test@test.com",
                        "passwordHash": "IR4uM8YiGpzevGjNYQHfFgFBkHqTqGy3rgCsA8d9LNZAmTItvy2l3MXSnPcXQD7QldV3X5GA/CKSF4mPCFkAYg==",
                        "passwordSalt": "XWzpfAf8IA7wpgY+gtVHiGPxTX4avvn38VY7MFspMhAfPUwL1a9ctuSQcEPlRJKqfK/3yZRtPWUlMQV7XH0JHRd4bKFvH/NKpSr4v46vOlgdQWAZDH1dklmqPtCmYK/Rq8SC/qcKfrmQLbJewBJ7B1Fse33ohAXp29+0K1c4YsE=",
                        "name": null,
                        "avatar": null,
                        "address": null,
                        "aboutMe": null,
                        "company": null,
                        "job": null,
                        "city": null,
                        "country": null,
                        "birthday": "0001-01-01T00:00:00",
                        "createdDate": "2020-04-08T02:38:40.288739",
                        "userOrganizations": null,
                        "ownerTasks": null,
                        "assignedTasks": null,
                        "assigneeTasks": null
                    },
                    "createdDate": "2020-04-08T02:09:46.1474742Z",
                    "tasks": [],
                    "parentId": 16,
                    "children": []
                }
            ]
        },
        "tasks": null,
        "parent": null,
        "parentId": null,
        "children": [
            {
                "id": 17,
                "name": "category2",
                "description": null,
                "createdBy": {
                    "id": 2,
                    "email": "test@test.com",
                    "passwordHash": "IR4uM8YiGpzevGjNYQHfFgFBkHqTqGy3rgCsA8d9LNZAmTItvy2l3MXSnPcXQD7QldV3X5GA/CKSF4mPCFkAYg==",
                    "passwordSalt": "XWzpfAf8IA7wpgY+gtVHiGPxTX4avvn38VY7MFspMhAfPUwL1a9ctuSQcEPlRJKqfK/3yZRtPWUlMQV7XH0JHRd4bKFvH/NKpSr4v46vOlgdQWAZDH1dklmqPtCmYK/Rq8SC/qcKfrmQLbJewBJ7B1Fse33ohAXp29+0K1c4YsE=",
                    "name": null,
                    "avatar": null,
                    "address": null,
                    "aboutMe": null,
                    "company": null,
                    "job": null,
                    "city": null,
                    "country": null,
                    "birthday": "0001-01-01T00:00:00",
                    "createdDate": "2020-04-08T02:38:40.288739",
                    "userOrganizations": null,
                    "ownerTasks": null,
                    "assignedTasks": null,
                    "assigneeTasks": null,
                    "currentOrganization": {
                        "id": 2,
                        "name": "Default",
                        "description": "",
                        "createdDate": "2020-04-07T23:38:40.459297",
                        "userOrganizations": [],
                        "hierarchies": []
                    }
                },
                "createdDate": "2020-04-08T02:09:46.1474742Z",
                "organization": {
                    "id": 2,
                    "name": "Default",
                    "description": "",
                    "createdDate": "2020-04-07T23:38:40.459297",
                    "userOrganizations": [],
                    "hierarchies": []
                },
                "tasks": [],
                "parentId": 16,
                "children": []
            }
        ]
    }
]

its going createdBy -> currentOrganization -> hierarchy

i dont need currentOrganization and hierarchy also createdBy object has user passwordHash

how can i customize my return value;


Solution

  • i dont need currentOrganization and hierarchy also createdBy object has user passwordHash

    It seems you do not want to show currentOrganization, hierarchy and passwordHash in createdBy object.

    Here are two ways to choose the return value:

    1.Use JsonIgnore Attribute:

    public class Hierarchy
    {
        public Hierarchy()
        {
            CreatedDate = DateTime.UtcNow;
            Children = new List<Hierarchy>();
        }
        public long Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public User CreatedBy { get; set; }
        public DateTime CreatedDate { get; set; }
        public Organization Organization { get; set; }       
        public Hierarchy Parent { get; set; }
        public long? ParentId { get; set; }
        public List<Hierarchy> Children { get; set; }
    }
    public class User
    {
        public int Id { get; set; }
        public string Email { get; set; }
        //more properties...
        [Newtonsoft.Json.JsonIgnore]
        public string PasswordHash { get; set; }
        [Newtonsoft.Json.JsonIgnore]
        public Organization CurrentOrganization { get; set; }
    }
    public class Organization
    {
        public int Id { get; set; }
        public string Name { get; set; }
        //more properties...
        public List<Hierarchy> Hierarchies { get; set; }
    }
    

    Controller:

    var d = _context.Hierarchies
                .Include(i=>i.Organization)
                .Include(i => i.Children)
                .Include(i => i.CreatedBy)
                .Where(x => x.Parent == null)
                .AsEnumerable()
                .ToList();
    

    Startup.cs:

    services.AddControllersWithViews().AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    });
    

    2.Create new View Model:

    ViewModel:

    public class HierarchyViewModel
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    
        public UserViewModel CreatedBy { get; set; }
    
        public DateTime CreatedDate { get; set; }
    
        public Organization Organization { get; set; }
    
        public Hierarchy Parent { get; set; }
        public long? ParentId { get; set; }
        public List<Hierarchy> Children { get; set; }
    }
    public class UserViewModel
    {
        public int Id { get; set; }
        public string Email { get; set; }
    }
    

    Controller:

    var d = _context.Hierarchies
                .Include(i=>i.Organization)
                .Include(i => i.Children)
                .Include(i => i.CreatedBy)
                .Where(x => x.Parent == null)
                .Select(x => new HierarchyViewModel()
                {
                    Id = x.Id,
                    CreatedDate = x.CreatedDate,
                    Description = x.Description,
                    Name = x.Name,
                    Parent = x.Parent,
                    Children = x.Children,
                    CreatedBy = new UserViewModel()
                    {
                        Id = x.CreatedBy.Id,
                        Email = x.CreatedBy.Email
                    },
                    ParentId = x.ParentId,
                    Organization = x.Organization
                }).ToList();
    

    Result:

    [
      {
        "id": 9,
        "name": "bbb",
        "description": "abb",
        "createdBy": {
          "id": 3,
          "email": "email2"
        },
        "createdDate": "2019-08-07T00:00:00",
        "organization": {
          "id": 1,
          "name": "org1",
          "hierarchies": [
            {
              "id": 8,
              "name": "asd",
              "description": "sda",
              "createdBy": null,
              "createdDate": "2019-08-06T00:00:00",
              "parent": null,
              "parentId": 9,
              "children": []
            }
          ]
        },
        "parent": null,
        "parentId": null,
        "children": [
          {
            "id": 8,
            "name": "aaa",
            "description": "aaa",
            "createdBy": null,
            "createdDate": "2019-08-06T00:00:00",
            "organization": {
              "id": 1,
              "name": "org1",
              "hierarchies": []
            },
            "parent": null,
            "parentId": 9,
            "children": []
          }
        ]
      }
    ]