In this article, we will be learning how to compare two JSON objects in C#.
Let’s dive in.
Data Preparation
For this article, we will be using a simple console application. Let’s create the console application and then install the Json.NET library by running the command:
Install-Package Newtonsoft.Json
Json.Net is rich in functionalities to ease the manipulation of JSON objects in C#, we can also use it to serialize objects or to iterate over JSON objects.
Having set up the application, let’s add a new TestData
class:
public class TestData { public string GeneratePlainJsonString() { const string jsonString = $$""" { "name": "Sporty Ride", "make": "Toyota", "model": "Supra" } """ ; return jsonString; } public string GenerateNestedJsonString() { const string jsonString = $$""" { "name": "Sporty Ride", "make": "Toyota", "model": "Supra", "price": { "amount": 40000.00, "currency": "USD" } } """ ; return jsonString; } }
The two methods return two JSON strings, which we will be comparing throughout this article.
Now that we have all the data we need set up, let’s look at how we can compare two JSON objects.
Comparing JSON Objects Using Json.NET
Some of the approaches we are going to look at when comparing JSON objects are:
- Using the JToken.DeepEquals method
- Comparing deserialized objects
- Using Json.NET with LINQ
That said, let’s create a new JsonComparison
class:
public class JsonComparison { public string PlainJsonString { get; set; } public string SecondPlainJsonString { get; set; } public string NestedJsonString { get; set; } public JsonComparison() { InitializeData(); } public void InitializeData() { var testData = new TestData(); PlainJsonString = testData.GeneratePlainJsonString(); SecondPlainJsonString = testData.GeneratePlainJsonString(); NestedJsonString = testData.GenerateNestedJsonString(); } }
The class has one InitializeData()
method, which initializes the three public properties of the class. We will be using this class to discuss the different approaches to comparing JSON objects.
Let’s proceed to look at the first approach.
Using JToken.DeepEquals Method
The JToken.DeepEquals
method is part of the Json.NET namespace. We use it when comparing two JSON objects, including the deeply nested objects. Using this method, we pass two JToken
objects as parameters. If the two objects are equal, the method returns true
, otherwise, it returns false
. With this brief explanation, let’s see how we can use this method to compare two JSON objects.
In our JsonComparison
class, let’s add a new CompareJsonObjectsUsingDeepEquals()
method:
public Dictionary<string, string> CompareJsonObjectsUsingDeepEquals() { var result = new Dictionary<string, string>(); var plainJsonObject = JToken.Parse(PlainJsonString); var secondJsonObject = JToken.Parse(SecondPlainJsonString); var nestedJsonObject = JToken.Parse(NestedJsonString); var arePlainObjectsEqual = JToken.DeepEquals(plainJsonObject, secondJsonObject); var isPlainAndNestedObjectEqual = JToken.DeepEquals(secondJsonObject, nestedJsonObject); ... }
We first initialize an empty dictionary that takes string key-value pairs. Then, we convert our JSON strings to JToken objects using the JToken.Parse
method. After that, we use the JToken.DeepEquals
method to compare the JToken objects. We declare two variables arePlainObjectsEqual
and isPlainAndNestedObjectEqual
which we assign the result of the comparison. The rest of the implementation can be found here.
If we were to print the results to the console, we’d get:
Plain Objects Result: The plain json objects are equal Nested Objects Resul: The plain and nested json objects not are equal
We expect this result, because PlainJsonString
and SecondPlainJsonString
properties have the same JSON string. However, the NestedJsonString
property has a nested JSON string which is not equal to the SecondPlainJsonString
JSON string.
Comparing Deserialized Objects
Let’s start with the creation of required classes:
public class Car { public string Name { get; set; } public string Make { get; set; } public string Model { get; set; } public Price Price { get; set; } } public class Price { public double Amount { get; set; } public string Currency { get; set; } }
Next, we can add a new CompareDeserializedJsonObjects()
method to our class:
public Dictionary<string, string> CompareDeserializedJsonObjects() { var result = new Dictionary<string, string>(); var car1 = JsonConvert.DeserializeObject<Car>(PlainJsonString); var car2 = JsonConvert.DeserializeObject<Car>(SecondPlainJsonString); var car3 = JsonConvert.DeserializeObject<Car>(NestedJsonString); ... }
This is only the main and important part of the implementation. The rest of the code can be found here.
In this method, we first deserialize the three JSON strings into Car
objects. Deserializing the JSON strings produces objects with this same schema.
After deserializing the objects, we use the Equals()
method to compare the objects. Before proceeding, let’s modify the Car
class by adding this method:
public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return false; } var car = (Car)obj; return Name == car.Name && Model == car.Model && Make == car.Make && Price == car.Price; }
In this case, we override the Object.Equals()
method by writing our own custom logic for comparing the objects. If you need more information on overriding the Equals
method, you can find it here.
Please note that in this example, we haven’t added an override for the GetHashCode()
method. However, it is good practice to always implement it, especially when working with collections of either HashSet or Dictionary types.
The CompareDeserializedJsonObjects()
method uses the Equals
method which we’ve implemented in the Car
class to compare the two deserialized objects.
Printing results of the comparison to the console, we’d get:
Plain Objects Result: The two deserialized plain json objects are equal Nested Objects Result: The plain and nested deserialized objects are not equal
Comparing deserialized objects involves a number of steps before finally getting the solution. This could be tedious if we were comparing objects with many fields. Now let’s look at an alternative approach.
Using Json.NET with LINQ To Compare JSON Objects
Let’s start off by adding a new method to the JsonComparison
class:
public Dictionary<string, string> CompareJsonObjectsUsingLinq() { var result = new Dictionary<string, string>(); var car1 = JObject.Parse(PlainJsonString); var car2 = JObject.Parse(SecondPlainJsonString); var car3 = JObject.Parse(NestedJsonString); var arePlainObjectsEqual = car1.Properties().All(p => p.Value.Equals(car2[p.Name])); var isPlainAndNestedObjectEqual = car3.Properties().All(p => p.Value.Equals(car1[p.Name])); ... }
In this method, we first convert the JSON strings into JObject
objects using JObject.Parse
. Then, we compare the two plain objects using LINQ by iterating through all the properties, checking whether the values of the properties match each property. If the values of the JSON properties are equal, the method returns true
, otherwise, it returns false
. The rest of the code is in our repository, please check it out.
This approach builds on LINQ functionality, and it’s quite straightforward. In cases where the JSON objects being compared are large, it can still get the job done.
Conclusion
In this article, we have discussed how we can compare two JSON objects in C#. We have looked at three different approaches that can be used when comparing the objects and how we can use each of them. Till next time, keep learning!