Allowing customization of JSON key ordering when serializing dictionaries
See original GitHub issueSource 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:
- Created 4 years ago
- Reactions:7
- Comments:8
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
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…
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.