wbish / jsondiffpatch.net

JSON object diffs and reversible patching (jsondiffpatch compatible)
MIT License
369 stars 83 forks source link

Json values are not compared according to json standards #33

Open Anthony-Breneliere opened 5 years ago

Anthony-Breneliere commented 5 years ago

According to Jsondiffpatch those two objects are differents:

{ temperature = 10.0 } and { temperature = 10 }

But according to json standards, those two objects should be the same because temperatures have the same value, and json standards does not differentiate float types and integer types.

However Json.net differentiate float types and integer types, and JValues are different if their types are different. In Jvalue.cs:

    private static bool ValuesEquals(JValue v1, JValue v2)
    {
        return (v1 == v2 || (v1._valueType == v2._valueType && Compare(v1._valueType, v1._value, v2._value) == 0));
    }

And Jsondiffpatch compares values based on the JValue.ValuesEquals function.

As a result, if I write a document { temperature = 0.0 } in CosmosDB, I retrieve a document { temperature = 0 } that Jsondiffpatch considers as different.

I asked ComosDb support and they responsded: The JSON type system as per standard does not have two separate types for integers and floating point numbers, and these values are considered equivalent by our system. If you want to preserve the text representation as is, you can encode this property as a string i.e. with quotes, but note for example that the string ordering rules will apply if you try to do queries with filters over this property using operators such as < or >.

EffortlessFury commented 4 years ago

The JSON spec is somewhat ambiguous on this topic. You can always write your own JsonConverter to customize how JSON.Net handles these types to suit your needs and should allow this library to work for you.

https://json-schema.org/understanding-json-schema/reference/numeric.html https://code-examples.net/en/q/142c665

Anthony-Breneliere commented 4 years ago

https://code-examples.net/en/q/142c665

As a solution I indeed replaced the whole float values by integer values before storing them in CosmosDb.

This example using a JsonConverter is interresting, thank you.