C# 如何在序列化期间让JSON.NET呈现前向引用
JSON.NET使用设置PreserveReferencesHandling=PreserveReferencesHandling.Objects在第一次出现时内联序列化重复出现的对象,并在后续出现时将其序列化为JSON引用。 我猜这样做是为了避免转发引用 例如: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 {
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; }
}