序列化模式以维护反向引用

时间:2013-08-29 16:29:38

标签: c# json serialization json.net

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

我想以两种方式序列化对象,因此我可以在对象中上下导航。

阅读Json.NET的文档,我发现能够通过添加以属性名称为后缀的shouldSerialize方法来有条件地序列化C#poco属性。

选择经理和员工班。一位经理有很多员工。我希望员工能够反向引导经理,但如果经理不是员工的财产,我只希望经理引用员工。

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

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

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

1 个答案:

答案 0 :(得分:1)

如果您以这种方式使用ShouldSerialize,那么您的反向引用将不会是反向引用。 Employee.Manager会指向不同的 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" }