示例#1
0
        protected JsonMemberInfo GetMemberInfo(JsonPath path, JToken data, JsonMemberInfo parent)
        {
            var info = new JsonMemberInfo { Value = data.ToString(), Parent = parent, Path = path };

            if (data.Type == JTokenType.Array)
            {
                info.Children = new SortedDictionary<string, JsonMemberInfo>();
                info.IsArray = true;
                var idx = 0;
                foreach (var entry in ((IList<JToken>)data))
                {
                    var key = idx.ToString(CultureInfo.InvariantCulture);
                    var newPath = new JsonPath { Property = key, IsIndexer = true };
                    newPath.Prev = path.Clone(newPath);
                    info.Children.Add(key, this.GetMemberInfo(newPath, entry, info));
                    idx++;
                }
            }
            if (data.Type == JTokenType.Object)
            {
                info.Children = new SortedDictionary<string, JsonMemberInfo>();
                info.IsObject = true;
                foreach (var entry in ((IDictionary<string, JToken>)data))
                {
                    var newPath = new JsonPath { Property = entry.Key, IsIndexer = false };
                    newPath.Prev = path.Clone(newPath);
                    info.Children.Add(entry.Key, this.GetMemberInfo(newPath, entry.Value, info));
                }
            }
            if (data.Type == JTokenType.Boolean)
            {
                info.Value = Convert.ToBoolean(data.ToString());
            }
            if (data.Type == JTokenType.Float)
            {
                info.Value = Convert.ToDouble(data.ToString());
            }
            if (data.Type == JTokenType.Integer)
            {
                info.Value = Convert.ToInt32(data.ToString());
            }
            if (data.Type == JTokenType.Guid)
            {
                info.Value = new Guid(data.ToString());
            }
            if (data.Type == JTokenType.String)
            {
                info.Value = Convert.ToString(data.ToString());
            }
            if (data.Type == JTokenType.Null)
            {
                info.Value = null;
            }
            if (data.Type == JTokenType.Date)
            {
                info.Value = DateTime.Parse(data.ToString());
            }
            return info;
        }
示例#2
0
        public string ApplyPatch(IEnumerable<JsonPatchBase> patches, string json)
        {
            var graph = _serializer.Deserialize(json);

            if (patches == null)
            {
                return json;
            }

            foreach (var patch in patches)
            {
                if (patch.Operation == JsonDiffPatchOperation.Remove)
                {
                    var root = patch.Path.GetRoot();
                    var memberInfo = graph.FindByPath(root, patch.Path);
                    if (memberInfo != null)
                    {
                        if (memberInfo.Parent != null)
                        {
                            memberInfo.Parent.Children.Remove(memberInfo.Parent.Children.Single(x => x.Value == memberInfo).Key);
                        }
                        else
                        {
                            if (memberInfo == graph)
                            {
                                graph = new JsonMemberInfo { Path = new JsonPath { Property = "$" } };
                            }
                            else
                            {
                                throw new Exception("Invalid JSON Graph Structure!");
                            }
                        }
                    }
                    else
                    {
                        throw new Exception("Invalid JSON Structure!");
                    }
                }
                if (patch.Operation == JsonDiffPatchOperation.Add)
                {
                    if (patch.Element is int)
                    {
                        var root = patch.Path.GetRoot();
                        var memberInfo = graph.FindByPath(root, patch.Path);
                        if (memberInfo != null)
                        {
                            if (memberInfo.IsArray)
                            {
                                var key = Convert.ToString(patch.Element);
                                if (!memberInfo.Children.ContainsKey(key))
                                {
                                    var info = new JsonMemberInfo
                                               	{
                                               		Parent = memberInfo,
                                               		Path = new JsonPath { IsIndexer = true, Property = key },
                                               		Value = patch.Value
                                               	};
                                    info.Path.Prev = memberInfo.Path.Clone(info.Path);
                                    memberInfo.Children.Add(key, info);
                                }
                                else
                                {
                                    throw new Exception("Invalid JSON Structure! Index already exists.");
                                }
                            }
                            else
                            {
                                throw new Exception("Invalid JSON Structure! Not an Array.");
                            }
                        }
                        else
                        {
                            throw new Exception("Invalid JSON Structure!");
                        }
                    }
                    if (patch.Element is string)
                    {
                        var root = patch.Path.GetRoot();
                        var memberInfo = graph.FindByPath(root, patch.Path);
                        if (memberInfo != null)
                        {
                            if (memberInfo.IsObject)
                            {
                                var key = Convert.ToString(patch.Element);
                                if (!memberInfo.Children.ContainsKey(key))
                                {
                                    var info = new JsonMemberInfo
                                               	{
                                               		Parent = memberInfo,
                                               		Path = new JsonPath { IsIndexer = false, Property = key },
                                               		Value = patch.Value
                                               	};
                                    info.Path.Prev = memberInfo.Path.Clone(info.Path);
                                    memberInfo.Children.Add(key, info);
                                }
                                else
                                {
                                    throw new Exception("Invalid JSON Structure! Property already exists.");
                                }
                            }
                            else
                            {
                                throw new Exception("Invalid JSON Structure! Not an Object.");
                            }
                        }
                        else
                        {
                            throw new Exception("Invalid JSON Structure!");
                        }
                    }
                }
            }

            return graph.ToJson(this._serializer);
        }