C# 如何在序列化期间让JSON.NET呈现前向引用

C# 如何在序列化期间让JSON.NET呈现前向引用,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,JSON.NET使用设置PreserveReferencesHandling=PreserveReferencesHandling.Objects在第一次出现时内联序列化重复出现的对象,并在后续出现时将其序列化为JSON引用。 我猜这样做是为了避免转发引用 例如: class Person { public string Name { get; set; } public Person Mother { get; set; } } var joni = new Person {

JSON.NET使用设置PreserveReferencesHandling=PreserveReferencesHandling.Objects在第一次出现时内联序列化重复出现的对象,并在后续出现时将其序列化为JSON引用。 我猜这样做是为了避免转发引用

例如:

class Person
{
    public string Name { get; set; }
    public Person Mother { get; set; }
}

var joni = new Person { Name = "Joni" };
var james = new Person { Name = "James", Mother = joni };

var people = new List<Person> { james, joni };

var json = JsonConvert.SerializeObject(people, Formatting.Indented,
    new JsonSerializerSettings {
       PreserveReferencesHandling = PreserveReferencesHandling.Objects });
相反,我想得到这个:

[
  {
    "$id": "1",
    "Name": "James",
    "Mother": {
      "$ref": "2"
    }
  },
  {
    "$id": "2",
    "Name": "Joni",
    "Mother": null    
  }
]
虽然两者实际上是相等的,但我发现第二种方法更为合理,尤其是在手工编辑JSON数据时,这是我在这方面的一个用例

有没有一种方法可以控制哪个实例被序列化为引用,或者我是否被这种第一次出现的行为所困扰

编辑


我尝试反序列化所需的JSON,发现JSON.NET无法正确执行此操作,因为存在正向引用。

发生的情况是,您正在Person变量中实例化Person变量。因此,当您创建子对象时:

class Person
{
    public string Name { get; set; }
    public Person Mother { get; set; }
}
您正在内部创建一个母变量,即Person类型变量,它具有常规Person变量所具有的所有属性,以及您获得的JSON文件


不必这样做,您可以尝试创建一个新的类母亲,该类母亲继承自类Person,并且只具有ID属性,因此,当您创建JSON文件时,您将获得预期的结果。

您必须使用它。为了满足您的需要,Json.NET将无法对Json进行单次流式读取和解析。它需要将整个内容加载到内存中,比如说,加载到JToken层次结构中,创建一个查找数据库,然后反序列化。我想您可以这样做:序列化到JToken,将$id节点从第一个事件移动到最浅的事件,然后保存;然后在反序列化过程中执行相反的操作。@dbc谢谢,我想我最好还是放弃它,因为这次的麻烦似乎不值得。$id属性是由序列化程序添加的,不在所示的Person类示例中,因此不在您描述的派生母类中。
class Person
{
    public string Name { get; set; }
    public Person Mother { get; set; }
}