using Newtonsoft.Json.Linq;
public static class Program
public static JObject FindDiff(JToken Current, JToken Model)
JObject diff = new JObject();
if (JToken.DeepEquals(Current, Model)) return diff;
var current = Current as JObject;
var model = Model as JObject;
var addedKeys = current.Properties().Select(c => c.Name).Except(model.Properties().Select(c => c.Name));
var removedKeys = model.Properties().Select(c => c.Name).Except(current.Properties().Select(c => c.Name));
var unchangedKeys = current.Properties().Where(c => JToken.DeepEquals(c.Value, Model[c.Name])).Select(c => c.Name);
foreach (var k in addedKeys)
foreach (var k in removedKeys)
var potentiallyModifiedKeys = current.Properties().Select(c => c.Name).Except(addedKeys).Except(unchangedKeys);
foreach (var k in potentiallyModifiedKeys)
var foundDiff = FindDiff(current[k], model[k]);
if(foundDiff.HasValues) diff[k] = foundDiff;
var current = Current as JArray;
var model = Model as JArray;
var plus = new JArray(current.Except(model, new JTokenEqualityComparer()));
var minus = new JArray(model.Except(current, new JTokenEqualityComparer()));
if (plus.HasValues) diff["+"] = plus;
if (minus.HasValues) diff["-"] = minus;
public static void Main()
{ "String", "A string" },
{ "Items", new JArray(1, 2) }
{ "String", "A string" },
{ "Items", new JArray(1, 2) }
JObject diff = FindDiff(o1, o2);
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject( diff ));