我正在反序列化下面的文档,其中包含使用两个保存相同数据的不同类的引用。一个是使用构造函数注入进行反序列化,另一个是使用属性注入进行反序列化。构造函数注入类无法设置父引用,但属性注入类很好。当然,无论采用何种方式,它们都应该正确地注入相同的数据。我已经写了一个测试来证明。
我错过了什么吗?
{
"Id": "1472538848721372202",
"Key": "website",
"Root": {
"$id": "1",
"Id": "1472459628771017730",
"Type": "cras",
"Content": {
"Name": "lorem"
},
"Parent": null,
"Children": [{
"$id": "2",
"Id": "1472459628812960771",
"Type": "morbi",
"Content": {
"Name": "ipsumdolor"
},
"Parent": {
"$ref": "1"
}
}]
}
}
反序列化测试。
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using Xunit;
using static dataapi.tests.HierarchyCtor;
using static dataapi.tests.HierarchyProp;
namespace dataapi.tests
{
public class JsonConstructorPropTest
{
[Fact]
public void GivenTheASameJsonWithParentReferencesWhenParsedUsingConstuctorAndPropertyInjectionThenTheTwoObjectShouldHoldTheSameData()
{
const string RootId = "1472459628771017730";
var json = "{\"Id\":\"1472538848721372202\",\"Key\":\"website\",\"Root\":{\"$id\":\"1\",\"Id\":\"1472459628771017730\",\"Type\":\"cras\",\"Content\":{\"Name\":\"lorem\"},\"Parent\":null,\"Children\":[{\"$id\":\"2\",\"Id\":\"1472459628812960771\",\"Type\":\"morbi\",\"Content\":{\"Name\":\"ipsumdolor\"},\"Parent\":{\"$ref\":\"1\"}}]}}";
var hierarchyProp = JsonConvert.DeserializeObject<HierarchyProp>(json);
TraverseHierarchyProp(hierarchyProp.Root, node =>
{
if (node.Id == RootId)
{
Assert.Null(node.Parent);
}
else
{
Assert.NotNull(node.Parent);
}
});
var hierarchyCtor = JsonConvert.DeserializeObject<HierarchyCtor>(json);
TraverseHierarchyCtor(hierarchyCtor.Root, node =>
{
if (node.Id == RootId)
{
Assert.Null(node.Parent);
}
else
{
Assert.NotNull(node.Parent);
}
});
}
private void TraverseHierarchyCtor(NodeCtor node, Action<NodeCtor> callback)
{
for (int index = 0; index < node.Children.Length; index++)
{
TraverseHierarchyCtor(node.Children[index], callback);
}
callback(node);
}
private void TraverseHierarchyProp(NodeProp node, Action<NodeProp> callback)
{
for (int index = 0; index < node.Children.Length; index++)
{
TraverseHierarchyProp(node.Children[index], callback);
}
callback(node);
}
}
[JsonObject(IsReference = false)]
public class HierarchyCtor
{
private readonly DateTime _updatedAt;
private readonly DateTime _createdAt;
private readonly NodeCtor _root;
private readonly string _key;
private readonly string _id;
public HierarchyCtor(string id, string key, NodeCtor root, DateTime createdAt, DateTime updatedAt)
{
_id = id;
_key = key;
_root = root;
_createdAt = createdAt;
_updatedAt = updatedAt;
}
public NodeCtor Root
{
get { return _root; }
}
[JsonObject(IsReference = true)]
public class NodeCtor
{
private readonly string _id;
private readonly string _type;
private readonly JObject _content;
private readonly NodeCtor[] _children;
private readonly NodeCtor _parent;
private readonly DateTime _updatedAt;
private readonly DateTime _createdAt;
public NodeCtor(string id, string type, JObject content, DateTime createdAt, DateTime updatedAt, NodeCtor Parent, params NodeCtor[] children)
{
_id = id;
_type = type;
_content = content;
_createdAt = createdAt;
_updatedAt = updatedAt;
_parent = Parent;
_children = children ?? new NodeCtor[] { };
}
public string Id
{
get { return _id; }
}
public NodeCtor Parent
{
get { return Parent; }
}
public NodeCtor[] Children
{
get { return _children; }
}
}
}
[JsonObject(IsReference = false)]
public class HierarchyProp
{
[JsonObject(IsReference = true)]
public class NodeProp
{
public NodeProp()
{
Children = new NodeProp[] { };
}
public string Id { get; set; }
public string Type { get; set; }
public JObject Content { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public NodeProp Parent { get; set; }
public NodeProp[] Children { get; set; }
}
public string Id { get; set; }
public string Key { get; set; }
public NodeProp Root { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
}