Order of serialized fields using JSON.NET

In my case Mattias' answer didn't work. The CreateProperties method was never called.

After some debugging of Newtonsoft.Json internals, I came up with another solution.

public class JsonUtility
{
    public static string NormalizeJsonString(string json)
    {
        // Parse json string into JObject.
        var parsedObject = JObject.Parse(json);

        // Sort properties of JObject.
        var normalizedObject = SortPropertiesAlphabetically(parsedObject);

        // Serialize JObject .
        return JsonConvert.SerializeObject(normalizedObject);
    }

    private static JObject SortPropertiesAlphabetically(JObject original)
    {
        var result = new JObject();

        foreach (var property in original.Properties().ToList().OrderBy(p => p.Name))
        {
            var value = property.Value as JObject;

            if (value != null)
            {
                value = SortPropertiesAlphabetically(value);
                result.Add(property.Name, value);
            }
            else
            {
                result.Add(property.Name, property.Value);
            }
        }

        return result;
    }
}

The supported way is to use the JsonProperty attribute on the class properties that you want to set the order for. Read the JsonPropertyAttribute order documentation for more information.

Pass the JsonProperty an Order value and the serializer will take care of the rest.

 [JsonProperty(Order = 1)]

This is very similar to the

 DataMember(Order = 1) 

of the System.Runtime.Serialization days.

Here is an important note from @kevin-babcock

... setting the order to 1 will only work if you set an order greater than 1 on all other properties. By default any property without an Order setting will be given an order of -1. So you must either give all serialized properties and order, or set your first item to -2


You can actually control the order by implementing IContractResolver or overriding the DefaultContractResolver's CreateProperties method.

Here's an example of my simple implementation of IContractResolver which orders the properties alphabetically:

public class OrderedContractResolver : DefaultContractResolver
{
    protected override System.Collections.Generic.IList<JsonProperty> CreateProperties(System.Type type, MemberSerialization memberSerialization)
    {
        return base.CreateProperties(type, memberSerialization).OrderBy(p => p.PropertyName).ToList();
    }
}

And then set the settings and serialize the object, and the JSON fields will be in alphabetical order:

var settings = new JsonSerializerSettings()
{
    ContractResolver = new OrderedContractResolver()
};

var json = JsonConvert.SerializeObject(obj, Formatting.Indented, settings);

Tags:

C#

Json

Json.Net