question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allowing customization of JSON key ordering when serializing dictionaries

See original GitHub issue

Source type

Dictionary<string, int> // for example, with ("a", 1), ("c", 2), and ("b", 3), added in that order.

Desired JSON

{"a":1,"b":3,"c":2}

Actual JSON

{"a":1,"c":2,"b":3}

Steps to reproduce

void Main() // in linqpad
{
    var d = new Dictionary<string, int>
    {
        ["a"] = 1,
        ["c"] = 2,
        ["b"] = 3,
    };
    var s = new JsonSerializerSettings
    {
        ContractResolver = new OrderedPropertyNamesContractResolver(StringComparer.OrdinalIgnoreCase),
    };
    JsonConvert.SerializeObject(d).Dump(); // yields {"a":1,"c":2,"b":3}, as expected.
    JsonConvert.SerializeObject(d, s).Dump(); // yields the same, but was hoping for {"a":1,"b":3,"c":2}
}

// My very naive attempt at doing this without constructing a whole new SortedDictionary or SortedList ---
class OrderedPropertyNamesContractResolver : DefaultContractResolver
{
    readonly IComparer<string> Comparer;

    public OrderedPropertyNamesContractResolver(IComparer<string> comparer) => Comparer = comparer ?? throw new ArgumentNullException(nameof(comparer));

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization).OrderBy(property => property.PropertyName, Comparer).ToList();
        foreach (var (property, index) in properties.Select(ValueTuple.Create<JsonProperty, int>))
        {
            property.Order = index;
        }
        return properties;
    }
}

Current workaround

Construct a SortedDictionary or SortedList with the same entries as the source dictionary, and then serialize that. Possibly insufficient when the dictionary is actually inside an aggregate that you’re serializing.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:7
  • Comments:8

github_iconTop GitHub Comments

2reactions
robheffo79commented, Sep 7, 2021

I personally would like to see this added. I am using Json serialisation to produce a “normalised” versions of arbitrary objects. Being able to ensure Dictionarys have consistantly ordered keys helps greatly because a dictionary doesn’t care about the order, just that a key is present or not, whereas the normalisation process does care about both the order and whether or not a key is present…

1reaction
rummelsworthcommented, Feb 4, 2020
  • (a) Agreed, as mentioned above.
  • (b) Agreed, but irrelevant as discussed above.
  • © Agreed, but the workaround is partial, as mentioned above.

No offense taken. I think it’s great you engaged with this. At the very least, our discussion has been a “smoke test” of the feature’s reasonableness. Thanks.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Json Serialize/Deserialize for a Dictionary with Custom Key ...
The string written for a key can be customized by either overriding ToString() for the key type or by implementing a TypeConverter. A ......
Read more >
How to Serialize a Dictionary to JSON in C# - Code Maze
Exploring how to serialize a dictionary to JSON using two of the most popular .NET libraries: Newtonsoft.Json and System.Text.Json.
Read more >
How to write custom converters for JSON serialization - .NET
Learn how to create custom converters for the JSON serialization classes that are provided in the System.Text.Json namespace.
Read more >
Custom serialization and deserialization contracts
Learn how to write your own contract resolution logic to customize the JSON contract for a type.
Read more >
Sorting a Python Dictionary: Values, Keys, and More
In this tutorial, you'll get the lowdown on sorting Python dictionaries. By the end, you'll be able to sort by key, value, or...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found