JSON.NET通过使用以下设置保留所有引用来支持循环引用序列化:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
settings.PreserveReferencesHandling = PreserveReferencesHandling.All;
这允许以下代码在没有错误的情况下运行,正确地序列化和反序列化对象,使其自引用保持不变。
public class SelfReferencingClass
{
public string Name;
public SelfReferencingClass Self;
public SelfReferencingClass() {Name="Default"; Self=this;}
}
SelfReferencingClass s = new SelfReferencingClass();
string jsondata = JsonConvert.SerializeObject( d, settings );
s = JsonConvert.DeserializeObject<SelfReferencingClass>( jsondata, settings );
jsondata字符串如下所示:
{"$id":"1","Name":"Default","Self":{"$ref":"1"}}
问题是…如果没有一个相应的客户端JavaScript库来解释这些引用,并支持对这些引用本身进行编码,那么JSON.NET的这一功能怎么有用呢?
哪个客户端库(例如JSON.stringfy)支持使用"$id"one_answers"$ref"字段的此功能/编码?如果不存在,是否有已知的方法为现有库添加支持
我自己添加支持将是一个非常简单的两步过程。首先,反序列化整个字符串,在创建每个对象时,使用其"$id"值作为键将其添加到字典中。当您遇到引用(仅由"$ref"属性组成的对象)时,您可以将其添加到对象+字段名的列表中,通过在创建对象的最终字典中查找其键,您可以返回该列表来替换遇到的每个引用。
有几个选项:
- Douglas Crockford的原始JSON库有一个名为cycle.js的插件,可以解析循环引用。另请参阅这个答案,它具有解析引用的方法的增强版本:解析JSON对象中的循环引用
- 更好地处理循环引用和对象图的谷物
- CircularJSON,它非常小,完全按照它所说的去做
话虽如此,我可能会重构我的设计以避免循环引用,因为JSON通常是核心组件,您可能希望使用经过良好测试和支持的主流库。避免循环引用的一种方法就是创建轻量级填充程序对象并序列化它们。或者实现覆盖序列化行为的自定义接口(如果您有权访问类)。您甚至可以使用反射来避免使用循环引用的属性,从而使其自动化。
@ungap/structured-clone
做得很好,并且符合标准。