使用Json.net反序列化文档,其引用使用属性而不是构造函数注入

时间:2017-03-30 23:03:30

标签: json parsing json.net hierarchy

我正在反序列化下面的文档,其中包含使用两个保存相同数据的不同类的引用。一个是使用构造函数注入进行反序列化,另一个是使用属性注入进行反序列化。构造函数注入类无法设置父引用,但属性注入类很好。当然,无论采用何种方式,它们都应该正确地注入相同的数据。我已经写了一个测试来证明。

我错过了什么吗?

{
    "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; }
    }
}

0 个答案:

没有答案