Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.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层次结构的集合导航属性_C#_Json.net_Postman_Navigation Properties - Fatal编程技术网

C# 返回奇数JSON层次结构的集合导航属性

C# 返回奇数JSON层次结构的集合导航属性,c#,json.net,postman,navigation-properties,C#,Json.net,Postman,Navigation Properties,我有两门课: public class A { public int Id { get; set; } public string Name { get; set; } public B myB { get; set; } } public class B { public int Id { get; set; } public string Name { get; set;

我有两门课:

    public class A
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public B myB { get; set; }
    }

    public class B
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ICollection<A> myAs { get; set; }
    }
相反,返回的是wierd层次结构:

    public IEnumerable<A> GetAs()
    {
        return _context.As.Include(a => a.myB).ToList();
    }
GetAs方法返回A对象和B对象以及进一步嵌套的A对象

经过一点研究后,我的理解是(我在这里可能大错特错),因为a对B(myB)有导航属性,B对a对象列表(MyA)有导航属性,这导致了某种循环

我的问题是

  • 我的理解正确吗?这就是为什么层次结构在这个奇怪的布局中返回的原因吗
  • 我该如何解决这个问题?我可以将ICollection navigation属性从域模型中移除,但是我不能再查询As及其关联的Bs
  • 注意A和B实际上不是我的域模型。我只是想让这个例子尽可能简单

    提前感谢。

    这里有几件事:

    输出具有预期的形状。正如您所怀疑的,序列化程序正在扩展双向引用。想想如果手动递归序列化每个对象的每个属性会发生什么。事情就是这样

    要解决眼前的问题,请按如下方式配置默认序列化程序设置:

    jsonFormatter.SerializerSettings.ReferenceLoopHandling  = Newtonsoft.Json.Serialization.ReferenceLoopHandling.Ignore;
    
    上述内容在原型化时非常有用,但当您的应用程序更正式时,您应该从web API端点创建并返回专用的视图模型类型

    public class AViewModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
    public class BViewModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public IEnumerable<AViewModel> myAs { get; set; }
    }
    
    public IEnumerable<BViewModel> GetBs()
    {
       return _context.Bs.Include(b => b.myAs)
            .Select(b => new BViewModel
            {
                Id = b.Id,
                Name = b.Name,
                As = b.As.Select(a => new AViewModel
                {
                     Id = a.Id,
                     Name = a.Name
                })
            })
            .ToList();
    }
    
    公共类AViewModel
    {
    公共int Id{get;set;}
    公共字符串名称{get;set;}
    }
    公共类BViewModel
    {
    公共int Id{get;set;}
    公共字符串名称{get;set;}
    公共IEnumerable myAs{get;set;}
    }
    公共IEnumerable GetBs()
    {
    return\u context.Bs.Include(b=>b.myAs)
    .选择(b=>newbviewmodel
    {
    Id=b.Id,
    Name=b.Name,
    As=b.As.Select(a=>newaviewmodel
    {
    Id=a.Id,
    姓名
    })
    })
    .ToList();
    }
    
    值得注意的是,有一些库,例如广受好评的AutoMapper,可以为您执行模型类型之间的这些转换,使用反射按名称自动指定相应的属性

    就我个人而言,我尽量避免使用基于反射的方法,因为它们倾向于使代码难以静态推理。这既妨碍了我们这样的人类读者,也妨碍了C语言这样的工具


    这就是说,根据手头的任务,权衡是值得的。我希望最终能看到语言级的支持,消除这种样板文件分配,而不必进入严格的领域,但我还有很长的时间等待。

    第二个JSON示例的格式不好。如果我把它上传到我得到一个错误
    error:Parse error在第12行:预期为'EOF',get','
    基本上它看起来像是一系列连接在一起的独立JSON文件。嗨,是的,我错过了开头和结尾的方括号。它现在生效了。对层次结构布局有什么想法吗?我完全不知道该做什么,谢谢你的回复。我已经添加了上面的JSON设置。这使我能够查看返回的JSON,而不会出现“自引用循环”错误。至于您的专用视图模型建议,您可以通过任何方式提供一个示例来说明这是如何工作的。我还是没有什么好运气。非常感谢你的帮助。非常感谢。我一定会去看看的。非常感谢你做的这件事。我更新了一些关于这些工具的陷阱的评论。祝你好运。如何完成相反的操作(GetAs)。我希望能够完成这两个操作(GetAs和GetBs),但在不更改模型(例如删除集合导航)的情况下看不到如何完成。属性并添加导航。财产返还给
    [
    {
            "Id": 1,
            "Name": "A1",
            "myB": {
                "Id": 1,
                "Name": "B2",
                "myAs": [
                    {
                        "Id": 2,
                        "Name": "A2"
                    }
                ]
            }
        },
        {
            "Id": 2,
            "Name": "A2",
            "myB": {
                "Id": 1,
                "Name": "B2",
                "myAs": [
                    {
                        "Id": 1,
                        "Name": "A1"
                    }
                ]
            }
        },
        {
            "Id": 3,
            "Name": "A3",
            "myB": {
                "Id": 2,
                "Name": "B3",
                "myAs": [
                    {
                        "Id": 4,
                        "Name": "A4"
                    },
                    {
                        "Id": 5,
                        "Name": "A5"
                    }
                ]
            }
        }
    ]
    
    jsonFormatter.SerializerSettings.ReferenceLoopHandling  = Newtonsoft.Json.Serialization.ReferenceLoopHandling.Ignore;
    
    public class AViewModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
    public class BViewModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public IEnumerable<AViewModel> myAs { get; set; }
    }
    
    public IEnumerable<BViewModel> GetBs()
    {
       return _context.Bs.Include(b => b.myAs)
            .Select(b => new BViewModel
            {
                Id = b.Id,
                Name = b.Name,
                As = b.As.Select(a => new AViewModel
                {
                     Id = a.Id,
                     Name = a.Name
                })
            })
            .ToList();
    }