Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort properties alphabetically when serializing JSON using Netwonsoft library?

When serializing objects using the Netwonsoft.JSON library, it's possible to specify the output order using JsonPropertyAttribute property Order. However, I would like to also sort alphabetically the properties by default on top of that.

like image 768
Michele Di Cosmo Avatar asked Jul 08 '19 11:07

Michele Di Cosmo


People also ask

Are JSON properties Order?

The JSON Data Interchange Standard definition at json.org specifies that “An object is an unordered [emphasis mine] set of name/value pairs”, whereas an array is an “ordered collection of values”. In other words, by definition the order of the key/value pairs within JSON objects simply does not, and should not, matter.

Can JSON serialize a list?

Json.NET has excellent support for serializing and deserializing collections of objects. To serialize a collection - a generic list, array, dictionary, or your own custom collection - simply call the serializer with the object you want to get JSON for.

How does the JsonProperty attribute affect JSON serialization?

JsonPropertyAttribute indicates that a property should be serialized when member serialization is set to opt-in. It includes non-public properties in serialization and deserialization. It can be used to customize type name, reference, null, and default value handling for the property value.


1 Answers

You can create a custom contract resolver, by extending Newtonsoft.Json.Serialization.DefaultContractResolver. The CreateProperties method is the one responsible of the property order, so overriding it, and re-sorting the properties would change the behaviour in the way you want:

public class OrderedContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
    protected override System.Collections.Generic.IList<Newtonsoft.Json.Serialization.JsonProperty> CreateProperties(System.Type type, Newtonsoft.Json.MemberSerialization memberSerialization)
    {
        var @base = base.CreateProperties(type, memberSerialization);
        var ordered = @base
            .OrderBy(p => p.Order ?? int.MaxValue)
            .ThenBy(p => p.PropertyName)
            .ToList();
        return ordered;
    }
}

In order to use a custom contract resolver you have to create a custom Newtonsoft.Json.JsonSerializerSettings and set its ContractResolver to an instance of it:

var jsonSerializerSettings = new Newtonsoft.Json.JsonSerializerSettings
{
    ContractResolver = new OrderedContractResolver(),
};

and then serialize using the above settings object's instance:

using (Newtonsoft.Json.JsonWriter writer = new Newtonsoft.Json.JsonTextWriter(sw))
{
    var serializer = Newtonsoft.Json.JsonSerializer.Create(jsonSerializerSettings);
    serializer.Serialize(writer, jsonObject);
}

where sw is a simple string writer:

var sb = new System.Text.StringBuilder();
var sw = new System.IO.StringWriter(sb);

and jsonObject is the object you wish to serialize.

like image 167
Michele Di Cosmo Avatar answered Sep 25 '22 13:09

Michele Di Cosmo