2

Here's the situation, I first generate 2 JSON from objects of each class of my model. One JSON is from my current model version and the other is from a previous version of it. My job is to compare each JSON to find where are the difference between the 2 models.

The problems is, the attributes of the objects are not serialized in the same order from one JSON to another.

Is there a way two serialize an object with all their attribute in alphabetical order, so I can compare both of the string easily ?

Thanks !

user2161442
  • 21
  • 1
  • 5
  • 1
    how are you *currently* serializing? – Peter Ritchie Apr 18 '13 at 15:27
  • Why don't you do the comparison of the objects before serialization, when you can do a property by property comparison without worrying about the results of serialization? – rclement Apr 18 '13 at 15:29
  • Because the JSON from the "Old Model" is store in a database i query, I dont have the objects themselves. What i'm doing right now is check if all attributes from the JSON of the "old model" are stille present and valid in the JSON of the same objects from the "new model", a regression test. – user2161442 Apr 18 '13 at 15:33

1 Answers1

4

If you just want to do a one time compare on 2 json strings there's this resource on the web

http://tlrobinson.net/projects/javascript-fun/jsondiff

In Json.Net there is a DeepEquals available on JToken so.

var json1 = JToken.Parse(jsonString1);
var json2 = JToken.Parse(jsonString2);
var jsonEqual = JToken.DeepEquals(json1, json2);

If you want to do exactly what you're asking Order the serialization see this post.

https://stackoverflow.com/a/11309106/1181408

Update - Show that Order serialization works fine.

public class OrderedContractResolver : DefaultContractResolver
{
    protected override System.Collections.Generic.IList<JsonProperty> CreateProperties(System.Type type, MemberSerialization memberSerialization)
    {
        return base.CreateProperties(type, memberSerialization).OrderBy(p => p.PropertyName).ToList();
    }
}

public class JsonSerializationTest1
{
    public string Test1 { get; set; }
    public string MyTest2 { get; set; }
    public string Test2 { get; set; }
    public string Test10 { get; set; }
}

public class JsonSerializationTest2
{
    public string Test10 { get; set; }
    public string Test1 { get; set; }
    public string MyTest2 { get; set; }
    public string Test2 { get; set; }
}

[TestMethod]
    public void TestJsonOrder()
    {
        var test1 = new JsonSerializationTest1 { Test1 = "abc", MyTest2 = "efg", Test10 = "hij", Test2 = "zyx" };
        var test2 = new JsonSerializationTest2 { Test1 = "abc", Test10 = "hij", Test2 = "zyx", MyTest2 = "efg" };

        var test1Json = JsonConvert.SerializeObject(test1);
        var test2Json = JsonConvert.SerializeObject(test2);

        Assert.AreNotEqual(test1Json, test2Json);

        var settings = new JsonSerializerSettings()
        {
            ContractResolver = new OrderedContractResolver()
        };

        var json1 = JsonConvert.SerializeObject(test1, Formatting.Indented, settings);
        var json2 = JsonConvert.SerializeObject(test2, Formatting.Indented, settings);

        Assert.AreEqual(json1, json2);

    }
Community
  • 1
  • 1
cgotberg
  • 2,045
  • 1
  • 18
  • 18
  • What doesn't seem to work. I added a quick example of how you would implement OrderedContractResolver and then serialize the classes. – cgotberg Apr 18 '13 at 18:19
  • DeepEquals return false if the elements in the two json are not in the same order – user2161442 Apr 18 '13 at 18:20
  • I haven't looked at the Json.Net Deep Equal code but that doesn't surprise me. – cgotberg Apr 18 '13 at 18:29
  • 1
    OrderedContractResolver doesn't apply to sub element of the json. The attributes of a serialized objects within another objects will not be in alphabetical order for instance. – user2161442 Apr 18 '13 at 19:17
  • Yeah it does. The properties of each object are sorted correctly. Now it doesn't sort a collection of items because it doesn't know how to. – cgotberg Apr 18 '13 at 19:33
  • ok.. i guess i'll just have to deserialized list's JSON to compare them properly – user2161442 Apr 19 '13 at 15:16