Description
Background and Motivation
As part of making more extensible POCO converters and community asks, a low-risk feature for specifying ordering of properties\fields on a POCO for serialization is possible in the V6 timeframe. Other extensibility POCO features are no longer feasible for V6 since they need 1-2 preview releases to be properly vetted.
Today the serializer depends on reflection order for serializing object properties, and does base classes afterwards. Reflection is currently not deterministic and sometimes control over base class ordering is desired such as specifying base properties first.
The simplest way to implement this is through an attribute that specifies the order. However, this only works for owned POCOs. For V7+ once the JsonPropertyInfo
is exposed publicly, that will allow for non-owned POCOs to also have this behavior.
Note that Newtonsoft has a similar approach with JsonPropertyAttribute.Order
.
The source-generator should also leverage this attribute.
Proposed API
namespace System.Text.Json.Serialization
{
+ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
+ public sealed class JsonPropertyOrderAttribute : JsonAttribute
+ {
+ public JsonPropertyNameAttribute(int order);
+ public int Order { get; }
+ }
}
Usage Examples
public class Person
{
[JsonPropertyOrder(-1)] // Always appear first
public int Id { get; set; }
[JsonPropertyOrder(1)] // appear before LastName
public string FirstName { get; set; }
[JsonPropertyOrder(2)]
public string LastName{ get; set; }
public string City{ get; set; } // No order defined (has a order value of 0)
}
If there is a "tie" in the values, the reflection order is used. This is also consistent with Newtsonsoft.
Alternative Designs
It is possible to add a "strategy" pattern here, like we do for property naming. However, as mentioned in the introduction, in V7+ allowing write access to the JsonPropertyInfo.Order
property will likely be the most natural mechanism once JsonPropertyInfo
is exposed publicly. This would be coupled with a mechanism to retrieve all properties, allowing, for example, properties to be sorted by base class first and\or sorted alphabetically without using [JsonPropertyOrder]
.