ValeraT1982 / ObjectsComparer

C# Framework provides mechanism to compare complex objects, allows to override comparison rules for specific properties and types.
MIT License
352 stars 86 forks source link

Comparing expandoObject deserialized via JsonSerializer does not work #43

Closed masherak closed 2 years ago

masherak commented 2 years ago

Helo, if I use deserialization method from class JsonSerializer and namespace: System.Text.Json so comparing end with zero differences everytime. If I use newtonsoft - JsonConvert it is working well.

ValeraT1982 commented 2 years ago

Can you please give an example?

masherak commented 2 years ago

namespace: System.Text.Json

image
ValeraT1982 commented 2 years ago

What framework do you use? What version of the JsonSerializer package? Line var deserializedValue1 = System.Text.Json.JsonSerializer.Deserialize<ExpandoObject>("JSON"); throws an exception because "JSON" isn't a valid JSON.

masherak commented 2 years ago

It is actual version of .NET 6

masherak commented 2 years ago

Yes "JSON" is really not valid JSON just replace it with some JSON with one field and you will se that it is not work.

ValeraT1982 commented 2 years ago

Please provide working code example, result and result you expect.

masherak commented 2 years ago
    var testObject1 = new
    {
        A = "ABC",
        B = "CBA"
    };

    var testObject2 = new
    {
        A = "CBA",
        B = "ABC"
    };

    var testJson1 = JsonSerializer.Serialize(testObject1);

    var testJson2 = JsonSerializer.Serialize(testObject2);

    Console.WriteLine($"testJson1: {testJson1}");
    Console.WriteLine($"testJson2: {testJson2}");

    var comparer = new Comparer(new ComparisonSettings { UseDefaultIfMemberNotExist = true });

    var deserializedValue1 = JsonSerializer.Deserialize<ExpandoObject>(testJson1);

    var deserializedValue2 = JsonSerializer.Deserialize<ExpandoObject>(testJson2);

    comparer.Compare (deserializedValue1, deserializedValue2, out var configurationDifferences);

    Console.WriteLine($"Count: {configurationDifferences.Count()}, Changes: {string.Join(',', configurationDifferences.Select(_ => $"{_.Value1} => {_.Value2}"))}");
masherak commented 2 years ago
image
masherak commented 2 years ago

With JsonSerializer you can see 0 changes, with JsonConvert it is work well.

ValeraT1982 commented 2 years ago

Now I see the problem. System.Text.Json.JsonSerializer.Deserialize(obj); returns Expando object and each property type is System.Text.Json.JsonElement. System.Text.Json.JsonElement has only 2 properties:

     public JsonElement this[int index] { get; }
     public JsonValueKind ValueKind { get; }

Only these 2 properties are used by comparer. It's why comparer says that objects are equal. As a solution, you can create a custom comparer for System.Text.Json.JsonElement and use Factory (https://github.com/ValeraT1982/ObjectsComparer#factory). I'll be considering fixing it in the next version.

masherak commented 2 years ago

Ok, thank you very much, have a nice day.