Order of serialized fields using JSON.NET
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);
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;
}
}