System.Text.Json – Control the order that properties get serialized

You can use the JsonPropertyOrder attribute to control the order that properties get serialized. You specify the order as an integer, and it serializes the properties in ascending order. Here’s an example:

using System.Text.Json.Serialization; public class Programmer { [JsonPropertyOrder(2)] public string LastName { get; set; } [JsonPropertyOrder(1)] public string FirstName { get; set; } [JsonPropertyOrder(-1)] public string Language { get; set; } }
Code language: C# (cs)

Note: Properties have a default order value of 0.

Now serialize a Programmer object:

using System.Text.Json; var json = JsonSerializer.Serialize(new Programmer() { FirstName = "Jason", LastName = "Bourne", Language = "C#", }, new JsonSerializerOptions() { WriteIndented = true }); Console.WriteLine(json);
Code language: C# (cs)

This generates the following JSON with the properties serialized in ascending order – Language (-1), FirstName (1), LastName (2):

{ "Language": "C#", "FirstName": "Jason", "LastName": "Bourne" }
Code language: JSON / JSON with Comments (json)

The JsonPropertyOrder attribute was added in System.Text.Json v6.0.0. Note: This package targets .NET Standard 2.0 – so you can use this feature even if you’re not on .NET 6.

Default property serialization order

When you use System.Text.Json to serialize an object, it uses reflection to get the declared (non-inherited) properties first. Then if you’re using inheritance, it will go through the inheritance hierarchy and get the inherited properties. Within each group of properties, there’s no guaranteed default order of serialization.

Why is there no guaranteed default order?

You may think it would serialize the properties based on the order they are declared in the class, but that’s not the case. The reason there’s no guaranteed default order of serialization is because it uses the reflective method Type.GetProperties(…) to get the properties, and this method doesn’t guarantee the order that properties are returned:

The GetProperties method does not return properties in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which properties are returned, because that order varies.

Ref: https://docs.microsoft.com/en-us/dotnet/api/system.type.getproperties?view=net-6.0

This explains why you have to use the JsonPropertyOrder attribute if you want to change the serialization order.

Declared properties first, then inherited properties

The only default serialization order you can be sure about is that declared (non-inherited) properties are serialized first, followed by the inherited properties. Here’s an example to show this.

Let’s say you have the following two classes. The Driver class subclasses the Person base class, inheriting all of its properties:

public abstract class Person { public string FirstName { get; set; } public string LastName { get; set; } public int Id { get; set; } } public class Driver : Person { public string Car { get; set; } }
Code language: C# (cs)

Serialize a Driver object:

using System.Text.Json; var json = JsonSerializer.Serialize(new Driver() { FirstName = "John", LastName = "Wick", Car = "Ford Mustang", Id = 123 }, new JsonSerializerOptions() { WriteIndented = true }); Console.WriteLine(json);
Code language: C# (cs)

Here’s the JSON this produces. Notice the Driver.Car property is first, followed by all of inherited properties from the Person base class:

{ "Car": "Ford Mustang", "FirstName": "John", "LastName": "Wick", "Id": 123 }
Code language: JSON / JSON with Comments (json)

Example – Serialize a base class property first

By default, base class properties are serialized last. One common scenario is wanting to serialize one or more base class properties first. Here’s an example of applying the JsonPropertyOrder attribute to a base class property to make sure it gets serialized first:

using System.Text.Json.Serialization; public abstract class Person { public string FirstName { get; set; } public string LastName { get; set; } [JsonPropertyOrder(-1000)] public int Id { get; set; } } public class Driver : Person { public string Car { get; set; } }
Code language: C# (cs)

Serialize a Driver object:

using System.Text.Json; var json = JsonSerializer.Serialize(new Driver() { FirstName = "James", LastName = "Bond", Car = "Aston Martin", Id = 456 }, new JsonSerializerOptions() { WriteIndented = true }); Console.WriteLine(json);
Code language: C# (cs)

Notice that it put the Id property from the Person base class first:

{ "Id": 456, "Car": "Aston Martin", "FirstName": "James", "LastName": "Bond" }
Code language: JSON / JSON with Comments (json)

1 thought on “System.Text.Json – Control the order that properties get serialized”

Leave a Comment