C# 用于维护反向引用的序列化模式

C# 用于维护反向引用的序列化模式,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,因此,如果两个对象之间存在一对多关系,则只能以一种方式序列化,否则在使用Json.NET时会出现周期性错误 我希望以两种方式序列化对象,以便可以在对象上下导航 在阅读Json.NET的文档时,我发现可以通过添加一个以属性名为后缀的shouldSerialize方法,有条件地序列化C#poco属性 以经理和员工为例。一个经理有很多员工。我希望员工反向引用经理,但我只希望经理在经理不是员工财产的情况下引用员工 { manager: { managerId: 1, attr1: 'b

因此,如果两个对象之间存在一对多关系,则只能以一种方式序列化,否则在使用Json.NET时会出现周期性错误

我希望以两种方式序列化对象,以便可以在对象上下导航

在阅读Json.NET的文档时,我发现可以通过添加一个以属性名为后缀的shouldSerialize方法,有条件地序列化C#poco属性

以经理和员工为例。一个经理有很多员工。我希望员工反向引用经理,但我只希望经理在经理不是员工财产的情况下引用员工

{ 
  manager: {
   managerId: 1,
   attr1: 'blah',

   employees: [
    {
     employeeId:1,
     manager: {
      manager id: 1,
      attr1: 'blah',
      employees: **null**
     }
   ]
}

这可能吗?最好的方法是什么?

如果您使用
应该以这种方式序列化,那么您的反向引用将不会是反向引用
Employee.Manager
将指向不同的
经理,而不是在其
Employees
属性中包含该员工的经理

您应该改用
JsonSerializerSettings.PreserveReferencesHandling
,这是专门为实现交叉链接和避免对象重复而设计的

class Program
{
    private static void Main ()
    {
        var m = new Manager { Attr = "Attr1" };
        var e = new Employee { Attr = "Attr1", Manager = m };
        m.Employees = new[] { e };
        Console.WriteLine(JsonConvert.SerializeObject(m,
            new JsonSerializerSettings {
                PreserveReferencesHandling = PreserveReferencesHandling.Objects,
                Formatting = Formatting.Indented,
            }));
        Console.ReadKey();
    }
}

class Manager
{
    public Employee[] Employees;
    public string Attr;
}

class Employee
{
    public Manager Manager;
    public string Attr;
}
此代码将输出以下JSON:

{
  "$id": "1",
  "Employees": [
    {
      "$id": "2",
      "Manager": {
        "$ref": "1"
      },
      "Attr": "Attr1"
    }
  ],
  "Attr": "Attr1"
}

请注意,现在所有对象都具有
$id
属性,当对象第二次出现在对象图中时,将插入对该对象的引用,而不是对象:
{“$ref”:“1”}

,因此如果我的任务是确定员工的经理,我将迭代管理器并将$ref属性与$id属性匹配。我几乎已经这样做了,但相反,我更深入了一个层次,查看每个经理的所有员工,并确定经理是否包含我正在查看的员工。考虑到json的约束,您所建议的这种方式更合理,似乎是最合理的解决方案。出于好奇,是否有支持反向引用的序列化格式?@Jesse XML本机支持id/idref,支持此功能。YAML支持引用,但它们更像是复制粘贴而不是实际引用,而且它的库非常糟糕。JSON不支持本地引用,但它可以很容易地扩展(就像在JSON.NET中那样)。另请参见维基百科页面:(我不知道大多数格式,因此无法对其发表评论。)