处理JSON.net中的引用循环 [英] Handling reference loops in JSON.net
问题描述
我希望将项目集合(List<Item>
)序列化为JSON.
I wish to serialize a collection (List<Item>
) of items to JSON.
这些项目具有Connection
的集合,该集合提供有关从一个Item
到第二个Item
的连接的信息.并且由于连接对象引用了项目,因此使其成为无限循环.
These items have a collection of Connection
which gives information about the connection from one Item
to a second Item
. And since the connection object has a reference to the items it makes it an infinite loop.
我的问题是,当我第二次序列化对象时,是否可以跳过连接集合的序列化.
我已经尝试了诸如从JsonConverter
继承并编写自定义WriteJson()
方法的操作,但是从那里我不知道是否应该写出数组.
I've tried things like inheriting from JsonConverter
and writing a custom WriteJson()
method but from there I have no sence whether I should write out the array or not.
我也尝试过使用自定义的ContractResolver,但效果不佳.
I've also tried using a custom ContractResolver but with no good results.
课程
public class Item
{
private static int _lastID = 0;
public Item()
{
ID = ++_lastID;
Connections = new List<Connection>();
}
public int ID { get; set; }
public string Name { get; set; }
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public List<Connection> Connections { get; set; }
}
public class Connection
{
private Connection(ConnectionType type, Item source, Item target)
{
if (type == ConnectionType.None)
throw new ArgumentException();
if (source == null)
throw new ArgumentNullException("source");
if (target == null)
throw new ArgumentNullException("target");
Type = type;
Source = source;
Target = target;
}
public ConnectionType Type { get; set; }
public Item Source { get; set; }
public Item Target { get; set; }
public static void Connect(ConnectionType type, Item source, Item target)
{
var conn = new Connection(type, source, target);
source.Connections.Add(conn);
target.Connections.Add(conn);
}
}
想要的结果:
[
{
"id": 1,
"name": "Item #1",
"prop1": "val1",
"prop2": "val2",
"connections": {
"type": "ConnType",
"source": {
"id": 1,
"name": "Item #1",
"prop1": "val1",
"prop2": "val2"
// no connections array
},
"target": {
"id": 2,
"name": "Item #2",
"prop1": "val1",
"prop2": "val2"
// no connections array
}
}
},
{
"id": 2,
"name": "Item #2",
"prop1": "val1",
"prop2": "val2",
"connections": {
"type": "ConnType",
"source": {
"id": 1,
"name": "Item #1",
"prop1": "val1",
"prop2": "val2"
// no connections array
},
"target": {
"id": 2,
"name": "Item #2",
"prop1": "val1",
"prop2": "val2"
// no connections array
}
}
}
]
C#
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Formatting = Formatting.Indented
};
settings.Converters.Add(new StringEnumConverter());
var json = JsonConvert.SerializeObject(collection, settings);
推荐答案
您可以引入一个新类,例如ItemClass
,而不是从Item
声明Source
和Target
的类型.将包含Item
类的所有字段,除了Connections
属性.
Instead of declaring the type of Source
and Target
as of Item
, you may introduce a new class, say, ItemClass
, which'll contain all the fields of class Item
, except the Connections
property.
public class ItemClass
{
public int ID { get; set; }
public string Name { get; set; }
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
public class Connection
{
// ...
public ConnectionType Type { get; set; }
public ItemClass Source { get; set; }
public ItemClass Target { get; set; }
// ...
}
现在,您将需要相应地填充新的ItemClass
类型实例的开销.
Now you'll have an overhead of populating the new ItemClass
type instance accordingly.
这篇关于处理JSON.net中的引用循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!