Edit

Share via


How to customize property names and values with System.Text.Json

By default, property names and dictionary keys are unchanged in the JSON output, including case. Enum values are represented as numbers. And properties are serialized in the order they're defined. However, you can customize these behaviors by:

  • Specifying specific serialized property names.
  • Using a built-in naming policy, such as camelCase, snake_case, or kebab-case, for property names and dictionary keys.
  • Using a custom naming policy for property names and dictionary keys.
  • Serializing enum values as strings, with or without a naming policy.
  • Configuring the order of serialized properties.

Note

The web default naming policy is camel case.

For other scenarios that require special handling of JSON property names and values, you can implement custom converters.

Customize individual property names

To set the name of individual properties, use the [JsonPropertyName] attribute.

Here's an example type to serialize and resulting JSON:

public class WeatherForecastWithPropertyName
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyName
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String

    <JsonPropertyName("Wind")>
    Public Property WindSpeed As Integer

End Class
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "Wind": 35
}

The property name set by this attribute:

Use a built-in naming policy

The following table shows the built-in naming policies and how they affect property names.

Naming policy Description Original property name Converted property name
CamelCase First word starts with a lower case character.
Successive words start with an uppercase character.
TempCelsius tempCelsius
KebabCaseLower* Words are separated by hyphens.
All characters are lowercase.
TempCelsius temp-celsius
KebabCaseUpper* Words are separated by hyphens.
All characters are uppercase.
TempCelsius TEMP-CELSIUS
SnakeCaseLower* Words are separated by underscores.
All characters are lowercase.
TempCelsius temp_celsius
SnakeCaseUpper* Words are separated by underscores.
All characters are uppercase.
TempCelsius TEMP_CELSIUS

* Available in .NET 8 and later versions.

The following example shows how to use camel case for all JSON property names by setting JsonSerializerOptions.PropertyNamingPolicy to JsonNamingPolicy.CamelCase:

var serializeOptions = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions);
Dim serializeOptions As JsonSerializerOptions = New JsonSerializerOptions With {
    .PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions)

Here's an example class to serialize and JSON output:

public class WeatherForecastWithPropertyName
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyName
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String

    <JsonPropertyName("Wind")>
    Public Property WindSpeed As Integer

End Class
{
  "date": "2019-08-01T00:00:00-07:00",
  "temperatureCelsius": 25,
  "summary": "Hot",
  "Wind": 35
}

The naming policy:

  • Applies to serialization and deserialization.
  • Is overridden by [JsonPropertyName] attributes. This is why the JSON property name Wind in the example is not camel case.

Note

None of the built-in naming policies support letters that are surrogate pairs. For more information, see dotnet/runtime issue 90352.

Use a custom JSON property naming policy

To use a custom JSON property naming policy, create a class that derives from JsonNamingPolicy and override the ConvertName method, as shown in the following example:

using System.Text.Json;

namespace SystemTextJsonSamples
{
    public class UpperCaseNamingPolicy : JsonNamingPolicy
    {
        public override string ConvertName(string name) =>
            name.ToUpper();
    }
}
Imports System.Text.Json

Namespace SystemTextJsonSamples

    Public Class UpperCaseNamingPolicy
        Inherits JsonNamingPolicy

        Public Overrides Function ConvertName(name As String) As String
            Return name.ToUpper()
        End Function

    End Class

End Namespace

Then set the JsonSerializerOptions.PropertyNamingPolicy property to an instance of your naming policy class:

var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = new UpperCaseNamingPolicy(),
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .PropertyNamingPolicy = New UpperCaseNamingPolicy,
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast1, options)

Here's an example class to serialize and JSON output:

public class WeatherForecastWithPropertyName
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyName
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String

    <JsonPropertyName("Wind")>
    Public Property WindSpeed As Integer

End Class
{
  "DATE": "2019-08-01T00:00:00-07:00",
  "TEMPERATURECELSIUS": 25,
  "SUMMARY": "Hot",
  "Wind": 35
}

The JSON property naming policy:

  • Applies to serialization and deserialization.
  • Is overridden by [JsonPropertyName] attributes. This is why the JSON property name Wind in the example is not upper case.

Use a naming policy for dictionary keys

If a property of an object to be serialized is of type Dictionary<string,TValue>, the string keys can be converted using a naming policy, such as camel case. To do that, set JsonSerializerOptions.DictionaryKeyPolicy to your desired naming policy. The following example uses the CamelCase naming policy:

var options = new JsonSerializerOptions
{
    DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast, options)

Serializing an object with a dictionary named TemperatureRanges that has key-value pairs "ColdMinTemp", 20 and "HotMinTemp", 40 would result in JSON output like the following example:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "TemperatureRanges": {
    "coldMinTemp": 20,
    "hotMinTemp": 40
  }
}

Naming policies for dictionary keys apply to serialization only. If you deserialize a dictionary, the keys will match the JSON file even if you set JsonSerializerOptions.DictionaryKeyPolicy to a non-default naming policy.

Enums as strings

By default, enums are serialized as numbers. To serialize enum names as strings, use the JsonStringEnumConverter or JsonStringEnumConverter<TEnum> converter. Only JsonStringEnumConverter<TEnum> is supported by the Native AOT runtime.

By default, enums are serialized as numbers. To serialize enum names as strings, use the JsonStringEnumConverter converter.

For example, suppose you need to serialize the following class that has an enum:

public class WeatherForecastWithEnum
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public Summary? Summary { get; set; }
}

public enum Summary
{
    Cold, Cool, Warm, Hot
}
Public Class WeatherForecastWithEnum
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As Summary
End Class

Public Enum Summary
    Cold
    Cool
    Warm
    Hot
End Enum

If the Summary is Hot, by default the serialized JSON has the numeric value 3:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": 3
}

The following sample code serializes the enum names instead of the numeric values, and converts the names to camel case:

options = new JsonSerializerOptions
{
    WriteIndented = true,
    Converters =
    {
        new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
    }
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
options = New JsonSerializerOptions With {
    .WriteIndented = True
}
options.Converters.Add(New JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
jsonString = JsonSerializer.Serialize(weatherForecast, options)

The resulting JSON looks like the following example:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "hot"
}

The built-in JsonStringEnumConverter can deserialize string values as well. It works with or without a specified naming policy. The following example shows deserialization using CamelCase:

options = new JsonSerializerOptions
{
    Converters =
    {
        new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
    }
};
weatherForecast = JsonSerializer.Deserialize<WeatherForecastWithEnum>(jsonString, options)!;
options = New JsonSerializerOptions
options.Converters.Add(New JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
weatherForecast = JsonSerializer.Deserialize(Of WeatherForecastWithEnum)(jsonString, options)

You can also specify the converter to use by annotating your enum with JsonConverterAttribute. The following example shows how to specify the JsonStringEnumConverter<TEnum> (available in .NET 8 and later versions) by using the JsonConverterAttribute attribute. For example, suppose you need to serialize the following class that has an enum:

public class WeatherForecastWithPrecipEnum
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public Precipitation? Precipitation { get; set; }
}

[JsonConverter(typeof(JsonStringEnumConverter<Precipitation>))]
public enum Precipitation
{
    Drizzle, Rain, Sleet, Hail, Snow
}

The following sample code serializes the enum names instead of the numeric values:

var options = new JsonSerializerOptions
{
    WriteIndented = true,
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);

The resulting JSON looks like the following example:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Precipitation": "Sleet"
}

To use the converter with source generation, see Serialize enum fields as strings.

Configure the order of serialized properties

By default, properties are serialized in the order in which they're defined in their class. The [JsonPropertyOrder] attribute lets you specify the order of properties in the JSON output from serialization. The default value of the Order property is zero. Set Order to a positive number to position a property after those that have the default value. A negative Order positions a property before those that have the default value. Properties are written in order from the lowest Order value to the highest. Here's an example:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace PropertyOrder
{
    public class WeatherForecast
    {
        [JsonPropertyOrder(-5)]
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        [JsonPropertyOrder(-2)]
        public int TemperatureF { get; set; }
        [JsonPropertyOrder(5)]
        public string? Summary { get; set; }
        [JsonPropertyOrder(2)]
        public int WindSpeed { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureC = 25,
                TemperatureF = 25,
                Summary = "Hot",
                WindSpeed = 10
            };

            var options = new JsonSerializerOptions { WriteIndented = true };
            string jsonString = JsonSerializer.Serialize(weatherForecast, options);
            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{
//  "Date": "2019-08-01T00:00:00",
//  "TemperatureF": 25,
//  "TemperatureC": 25,
//  "WindSpeed": 10,
//  "Summary": "Hot"
//}

Use Github Copilot to customize property names and order

You can use GitHub Copilot in your IDE to generate code to customize names and order of serialized properties.

If you're using Visual Studio 2022 version 17.8 or later, you can try the AI-driven GitHub Copilot in Visual Studio to generate code that uses System.Text.Json to customize property names and order in the JSON output from serializtion. Submit your question as a prompt in the Copilot chat window, as in the following example. You can also submit prompts using inline chat in the editor window itself.

Note

GitHub Copilot is powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions. For more information about the general use of GitHub Copilot, product impact, human oversight, and privacy, see GitHub Copilot FAQs.

The following example shows you how to use Copilot to modify existing code to customize property names and order when serializing to JSON.

  1. Add the following C# example code to a code file Example.cs in your editor. In Visual Studio, you can use a C# console application project to try this example.

    using System.Text.Json;
    
    public class Person
    {
        public string? FirstName { get; set; }
        public string? LastName { get; set; }
        public int Age { get; set; }
        public string? Country { get; set; }
    }
    
    public class Program
    {
        public static void Main()
        {
            var person = new Person
            {
                FirstName = "John",
                LastName = "Doe",
                Age = 30,
                Country = "USA"
            };
    
            string jsonString = JsonSerializer.Serialize(person);
            Console.WriteLine(jsonString);
        }
    }
    

    Example.cs code does the following:

    • Creates an instance of the Person class and initializes its properties with values.
    • Serializes the person object to a JSON string using JsonSerializer.Serialize.
    • Prints the following JSON string to the console:
    {"FirstName":"John","LastName":"Doe","Age":30,"Country":"USA"}
    
  2. In Copilot Chat, enter the following prompt to modify the code to customize names and order of the JSON serialization output.

    #Example.cs modify code to use System.Text.Json to customize property names and order of JSON output from serialization. Set property names: FirstName to first_name, LastName to last_name. Set order to: Country, FirstName, LastName, Age. Provide customized serialization output.

    #Example.cs in the prompt provides a file reference as context to Copilot. You can customize the prompt to output a JSON string with property names and values that suit your requirements. To set intent and get better answers with scoped context, you can use chat features such as slash commands, references to files, methods, or classes, and threads.

    The following output shows an example Copilot Chat response:

    To customize the property names and order of the JSON output using System.Text.Json, you can use the JsonPropertyName attribute to rename properties and the JsonPropertyOrder attribute to set the order. Here's how you can modify your code:
    
    using System.Text.Json;
    using System.Text.Json.Serialization;
    
    public class Person
    {
        [JsonPropertyName("first_name")]
        [JsonPropertyOrder(2)]
        public string? FirstName { get; set; }
    
        [JsonPropertyName("last_name")]
        [JsonPropertyOrder(3)]
        public string? LastName { get; set; }
    
        [JsonPropertyOrder(4)]
        public int Age { get; set; }
    
        [JsonPropertyOrder(1)]
        public string? Country { get; set; }
    }
    
    public class Program
    {
        public static void Main()
        {
            var person = new Person
            {
                FirstName = "John",
                LastName = "Doe",
                Age = 30,
                Country = "USA"
            };
    
            string jsonString = JsonSerializer.Serialize(person, new JsonSerializerOptions { WriteIndented = true });
            Console.WriteLine(jsonString);
        }
    }
    
    **Explanation:**
    
    1. Renaming Properties: The JsonPropertyName attribute is used to rename FirstName to first_name and LastName to last_name.
    2. Ordering Properties: The JsonPropertyOrder attribute is used to set the order of the properties in the JSON output. The order is set as:
       • Country (Order 1)
       • FirstName (Order 2)
       • LastName (Order 3)
       • Age (Order 4)
    3. Indented JSON: The JsonSerializerOptions with WriteIndented = true is used to make the JSON output more readable.
    
    **Customized Serialization Output:**
    {
      "Country": "USA",
      "first_name": "John",
      "last_name": "Doe",
      "Age": 30
    }
    
    This ensures that the JSON output has the customized property names and the specified order.
    

When Copilot returns a code block, the response includes options to copy the code, insert the code into a new file, or preview the code output.

Note

Your results might be different from what's shown in the example responses. AI models are non-deterministic, which means that they can return different responses when asked the same question. This might be due to additional learning and adaption over time, language variation, changes in context, such as your chat history, and more.

See also