8

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.stringify)支持使用“$id”和“$ref”字段的此功能/编码?如果不存在,是否有已知的方法可以向现有库添加支持?

自己添加支持将是一个非常简单的两遍过程。首先,反序列化整个字符串,并在创建每个对象时将其添加到字典中,使用其“$id”值作为键。当您遇到引用(仅由“$ref”属性组成的对象)时,您可以将其添加到对象+字段名列表中,您可以通过在创建对象的最终字典中查找其键来返回以替换每个遇到的引用.

4

1 回答 1

2

有几个选项:

  1. Douglas Crockford 的原始 JSON 库有一个名为cycle.js的插件,可以解析循环引用。另请参阅此答案,它具有解析引用的方法的增强版本:Resolve circular references from JSON object
  2. Cereal可以更好地处理循环引用和对象图。
  3. CircularJSON非常小并且完全按照它所说的那样做。

话虽如此,我可能会重构我的设计以避免循环引用,因为 JSON 通常是核心组件,您可能希望使用经过良好测试和支持的主流库。避免循环引用的一种方法是创建轻量级 shim 对象并将它们序列化。或者实现覆盖序列化行为的自定义接口(如果您有权访问类)。您甚至可以使用反射将其自动化,以避免具有循环引用的属性。

于 2014-03-07T08:31:21.677 回答