public void CreatePatch(JToken original, JToken modified, JsonPatchPath path, IPatchContext context) { var originalObj = (JObject)original; var modifiedObj = (JObject)modified; var allProperties = new HashSet <string>(); AddProperties(allProperties, originalObj); AddProperties(allProperties, modifiedObj); foreach (var propertyName in allProperties) { var originalValue = GetPropertyValue(originalObj, propertyName); var modifiedValue = GetPropertyValue(modifiedObj, propertyName); var propertyPath = path.AddSegment(propertyName); context.CreatePatch(originalValue, modifiedValue, propertyPath); } }
public void CreatePatch(JToken original, JToken modified, JsonPatchPath path, IPatchContext context) { var originalArr = (JArray)original; var modifiedArr = (JArray)modified; var items = originalArr.ToList(); // remove all items that were removed var newArrayItems = modifiedArr.ToList(); for (var i = items.Count - 1; i >= 0; i--) { var item = items[i]; var existingIndex = newArrayItems.FindLastIndex(x => JToken.DeepEquals(x, item)); if (existingIndex > -1) { newArrayItems.RemoveAt(existingIndex); } else { context.Document.Remove(path.AtIndex(i).ToString()); items.RemoveAt(i); } } // either move or add items that changed for (var i = 0; i < modifiedArr.Count; i++) { var modifiedItem = modifiedArr[i]; var existingItem = items.FindIndex(token => JToken.DeepEquals(modifiedItem, token)); if (existingItem > -1) { if (existingItem == i) { continue; } var origItem = items[existingItem]; var sourcePath = path.AtIndex(existingItem); var targetPath = path.AtIndex(i); if (modifiedArr.Count > existingItem && JToken.DeepEquals(modifiedArr[existingItem], origItem)) { // the item also exists at the current position, we have to copy context.Document.Copy(sourcePath.ToString(), targetPath.ToString()); items.Insert(i, origItem); } else { context.Document.Move(sourcePath.ToString(), targetPath.ToString()); items.RemoveAt(existingItem); items.Insert(i, origItem); } } else { var itemPath = items.Count == i?path.AddSegment("-") : path.AtIndex(i); context.Document.Add(itemPath.ToString(), modifiedItem); items.Insert(i, modifiedItem); } } }