I am using JsonNode.ToJsonString(...) in my unit tests. Unfortunately the property order in the serialized string seems to be depend the runtime order how the child nodes and value nodes were added.
However to phrase a unit test expectation the order would be deterministic to allow to be equal to the expectation.
I reviewed the serializer options but did not find anything related
Question
Is there any way to JsonNode.ToJsonString(...) produce properties in alphabetic order?
There is no built-in functionality to do this, however you could create a custom
JsonConverter<JsonNode>that alphabetizes the properties as they are written. Then you could serialize your node to JSON usingJsonSerializer.Serialize(node, options)with the converter added toJsonSerializerOptions.Converters.First, define the following extension method and converter:
And now you will be able to do:
Notes:
I used
StringComparer.Ordinalbecause it seems to corresponds to the sorting requirement from RFC 8785: JSON Canonicalization Scheme (JCS).While the above converter will work with any
JsonNodereturned fromJsonNode.Parse(), created from aJsonElement, or built up from primitive keys and values as shown in the doc example, it is also possible to create aJsonValuewith any POCO at all as its value, e.g.:Such cases get formatted to JSON as objects, not a primitive values:
I don't know why Microsoft provided such functionality, but when formatting such a node to JSON the code invokes the serializer to serialize its contents. Thus the converter above will not be invoked to alphabetize properties in such a strange case.
As an alternative to alphabetizing
JsonNodeproperties while writing, you could useJsonElementComparerfrom this answer to What is equivalent in JToken.DeepEquals in System.Text.Json? to compare JSON elements and ignore property order.Demo fiddle here.