For example, if I have the following json texts:
object1{
field1: value1;
field2: value2;
field3: value3;
}
object1{
field1: value1;
field2: newvalue2;
field3: value3;
}
I need something in c# that reads that files and shows the difference. i.e. it can return the following object:
differences {
object1: { field: field2, old_value: value2, new_value: newvalue2}
}
Is there some API or suggestions to do this?
Comparing Json: Comparing json is quite simple, we can use '==' operator, Note: '==' and 'is' operator are not same, '==' operator is use to check equality of values , whereas 'is' operator is used to check reference equality, hence one should use '==' operator, 'is' operator will not give expected result.
var result = diffObj. Diff(json1, json2); Other important thing to mention is that the Diff method can also receive as parameters JTokens (and, in this case, it returns a JToken with the diff), which might be useful if you are working with Json.net. After getting the diff JSON, we can simply print it to the console.
You can also directly compare two JSON files by specifying their urls in the GET parameters url1 and url2. Then you can visualize the differences between the two JSON documents. It highlights the elements which are different: Different value between the two JSON: highlight in red color.
I recommend you use Weakly-Typed JSON Serialization and write a routine that uses JsonObject like this:
String JsonDifferenceReport(String objectName,
JsonObject first,
JsonObject second)
{
if(String.IsNullOrEmpty(objectName))
throw new ArgumentNullException("objectName");
if(null==first)
throw new ArgumentNullException("first");
if(null==second)
throw new ArgumentNullException("second");
List<String> allKeys = new List<String>();
foreach(String key in first.Keys)
if (!allKeys.Any(X => X.Equals(key))) allKeys.Add(key);
foreach(String key in second.Keys)
if (!allKeys.Any(X => X.Equals(key))) allKeys.Add(key);
String results = String.Empty;
foreach(String key in allKeys)
{
JsonValue v1 = first[key];
JsonValue v1 = second[key];
if (((null==v1) != (null==v2)) || !v1.Equals(v2))
{
if(String.IsNullOrEmpty(results))
{
results = "differences: {\n";
}
results += "\t" + objectName + ": {\n";
results += "\t\tfield: " + key + ",\n";
results += "\t\toldvalue: " + (null==v1)? "null" : v1.ToString() + ",\n";
results += "\t\tnewvalue: " + (null==v2)? "null" : v2.ToString() + "\n";
results += "\t}\n";
}
}
if(!String.IsNullOrEmpty(results))
{
results += "}\n";
}
return results;
}
Your choice whether to get reports recursively inside JsonValue
v1 and v2, instead of just using their string representation as I did here.
If you wanted to go recursive, it might change the above like this:
if ((null==v1) || (v1.JsonType == JsonType.JsonPrimitive)
|| (null==v2) || (v2.JsonType == JsonType.JsonPrimitive))
{
results += "\t\tfield: " + key + ",\n";
results += "\t\toldvalue: " + (null==v1) ? "null" : v1.ToString() + ",\n";
results += "\t\tnewvalue: " + (null==v2) ? "null" : v2.ToString() + "\n";
}
else
{
results + JsonDifferenceReport(key, v1, v2);
}
-Jesse
I've constructed my own method for Json comparison. It uses Newtonsoft.Json.Linq.
public static JObject FindDiff(this JToken Current, JToken Model)
{
var diff = new JObject();
if (JToken.DeepEquals(Current, Model)) return diff;
switch(Current.Type)
{
case JTokenType.Object:
{
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)
{
diff[k] = new JObject
{
["+"] = Current[k]
};
}
foreach (var k in removedKeys)
{
diff[k] = new JObject
{
["-"] = Model[k]
};
}
var potentiallyModifiedKeys = current.Properties().Select(c => c.Name).Except(addedKeys).Except(unchangedKeys);
foreach (var k in potentiallyModifiedKeys)
{
diff[k] = FindDiff(current[k], model[k]);
}
}
break;
case JTokenType.Array:
{
var current = Current as JArray;
var model = Model as JArray;
diff["+"] = new JArray(current.Except(model));
diff["-"] = new JArray(model.Except(current));
}
break;
default:
diff["+"] = Current;
diff["-"] = Model;
break;
}
return diff;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With