Поделиться через


Как настроить имена и значения свойств с помощью System.Text.Json

По умолчанию имена и ключи словарей не изменяются в выходных данных JSON, включая регистр. Значения перечисления представлены в виде чисел. И свойства сериализуются в том порядке, в который они определены. Однако эти действия можно настроить следующим образом:

  • Указание определенных сериализованных имен свойств.
  • Используя встроенную политику именования, например верблюдьи Регистр, snake_case или kebab-case, для имен свойств и ключей словаря.
  • Использование настраиваемой политики именования для имен свойств и ключей словаря.
  • Сериализация значений перечисления в виде строк с политикой именования или без нее.
  • Настройка порядка сериализованных свойств.

Примечание.

Политика именования веб-сайта по умолчанию является верблюдю.

Для других сценариев, требующих специальной обработки имен и значений свойств JSON, можно реализовать пользовательские преобразователи.

Настройка отдельных имен свойств

Чтобы задать имена отдельных свойств, используйте атрибут [JsonPropertyName].

Ниже приведен пример типа для сериализации и полученный код 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
}

Имя свойства, заданное этим атрибутом:

Использование встроенной политики именования

В следующей таблице показаны встроенные политики именования и их влияние на имена свойств.

Политика именования Description Имя исходного свойства Имя преобразованного свойства
CamelCase Первое слово начинается с символа нижнего регистра.
Последовательные слова начинаются с символа верхнего регистра.
TempCelsius tempCelsius
KebabCaseLower* Слова разделяются дефисом.
Все символы являются строчными буквами.
TempCelsius temp-celsius
KebabCaseUpper* Слова разделяются дефисом.
Все символы являются прописными буквами.
TempCelsius TEMP-CELSIUS
SnakeCaseLower* Слова разделяются подчеркиваниями.
Все символы являются строчными буквами.
TempCelsius temp_celsius
SnakeCaseUpper* Слова разделяются подчеркиваниями.
Все символы являются прописными буквами.
TempCelsius TEMP_CELSIUS

* Доступно в .NET 8 и более поздних версиях.

В следующем примере показано, как использовать верблюдю регистр для всех имен свойств JSON, задав JsonSerializerOptions.PropertyNamingPolicy значение 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)

Ниже приведен пример класса для сериализации и вывода 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
}

Политика именования:

  • Применяется к сериализации и десериализации.
  • Переопределяется атрибутами [JsonPropertyName]. Именно поэтому имя свойства JSON, Wind в примере, не указано в "верблюжьем" стиле.

Примечание.

Ни одна из встроенных политик именования не поддерживает письма, которые являются суррогатными парами. Дополнительные сведения см. в статье dotnet/runtime issue 90352.

Использование настраиваемой политики именования свойств JSON

Чтобы использовать настраиваемую политику именования свойств JSON, создайте класс, производный от JsonNamingPolicy, и переопределите метод ConvertName, как показано в следующем примере:

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

Затем задайте для свойства JsonSerializerOptions.PropertyNamingPolicy экземпляр класса политики именования:

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)

Ниже приведен пример класса для сериализации и вывода 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
}

Политика именования свойств JSON:

  • Применяется к сериализации и десериализации.
  • Переопределяется атрибутами [JsonPropertyName]. Именно поэтому имя свойства JSON, Wind в примере, не указано в верхнем регистре.

Использование политики именования для ключей словаря

Если свойство сериализованного объекта имеет тип Dictionary<string,TValue>, string ключи можно преобразовать с помощью политики именования, например верблюдьего регистра. Для этого задайте JsonSerializerOptions.DictionaryKeyPolicy нужную политику именования. В следующем примере используется CamelCase политика именования:

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)

Сериализация объекта с помощью словаря с именем TemperatureRanges, имеющего пары "ключ-значение" "ColdMinTemp", 20 и "HotMinTemp", 40, приведет к выходным данным JSON, как в следующем примере:

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

Политики именования для ключей словаря применяются только к сериализации. Если вы десериализируете словарь, ключи будут соответствовать JSON-файлу, даже если задана JsonSerializerOptions.DictionaryKeyPolicy политика именования по умолчанию.

Перечисление в виде строк

По умолчанию перечисления сериализуются как числа. Для сериализации имен перечислений в виде строк используйте JsonStringEnumConverter преобразователь.JsonStringEnumConverter<TEnum> Поддерживается только JsonStringEnumConverter<TEnum> средой выполнения AOT в машинном коде.

По умолчанию перечисления сериализуются как числа. Чтобы сериализовать имена перечислений в виде строк, используйте преобразователь JsonStringEnumConverter .

Например, предположим, что необходимо сериализовать следующий класс, имеющий перечисление:

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

Если параметр "Сводка" имеет значение Hot, то по умолчанию сериализованный код JSON имеет числовое значение 3:

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

Следующий пример кода сериализует имена перечислений вместо числовых значений и преобразует имена в "верблюжий" стиль:

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)

Итоговый код JSON выглядит следующим образом:

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

Встроенные JsonStringEnumConverter также могут десериализировать строковые значения. Он работает с указанной политикой именования или без нее. В следующем примере показано десериализация с помощью 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)

Вы также можете указать преобразователь, который будет использоваться путем аннотирования перечисления.JsonConverterAttribute В следующем примере показано, как указать JsonStringEnumConverter<TEnum> (доступное в .NET 8 и более поздних версиях) с помощью атрибута JsonConverterAttribute . Например, предположим, что необходимо сериализовать следующий класс, имеющий перечисление:

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
}

Следующий пример кода сериализует имена перечислений вместо числовых значений:

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

Итоговый код JSON выглядит следующим образом:

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

Сведения об использовании преобразователя с исходным поколением см. в разделе "Сериализация полей перечисления в виде строк".

Настройка порядка сериализованных свойств

По умолчанию свойства сериализуются в порядке, в котором они определены в своем классе. Атрибут [JsonPropertyOrder] позволяет указать порядок свойств в выходных данных JSON из сериализации. Значение Order свойства по умолчанию равно нулю. Задайте Order положительное число, чтобы разместить свойство после тех, которые имеют значение по умолчанию. Отрицательное Order положение свойства перед теми, которые имеют значение по умолчанию. Свойства записываются в порядке от наименьшего Order значения до самого высокого. Приведем пример:

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"
//}

Настройка имен свойств и порядка с помощью Github Copilot

Вы можете использовать GitHub Copilot в интегрированной среде разработки для создания кода для настройки имен и порядка сериализованных свойств.

Если вы используете Visual Studio 2022 версии 17.8 или более поздней версии, вы можете попробовать GitHub Copilot на основе ИИ в Visual Studio создать код, который используется System.Text.Json для настройки имен свойств и порядка в выходных данных JSON из сериализации. Отправьте свой вопрос в виде запроса в окне чата Copilot, как показано в следующем примере. Вы также можете отправлять запросы с помощью встроенного чата в самом окне редактора.

Примечание.

GitHub Copilot работает СИ, поэтому возможны сюрпризы и ошибки. Обязательно проверьте любой созданный код или предложения. Дополнительные сведения об общем использовании GitHub Copilot, влиянии на продукты, надзоре и конфиденциальности см . в часто задаваемых вопросы о GitHub Copilot.

В следующем примере показано, как использовать Copilot для изменения существующего кода для настройки имен свойств и порядка при сериализации в JSON.

  1. Добавьте следующий пример кода C# в файл Example.cs кода в редакторе. В Visual Studio можно использовать проект консольного приложения C#, чтобы попробовать этот пример.

    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 Код выполняет следующее:

    • Создает экземпляр Person класса и инициализирует его свойства со значениями.
    • Сериализует person объект в строку JSON с помощью JsonSerializer.Serialize.
    • Выводит следующую строку JSON в консоль:
    {"FirstName":"John","LastName":"Doe","Age":30,"Country":"USA"}
    
  2. В Copilot Chat введите следующий запрос, чтобы изменить код для настройки имен и порядка выходных данных сериализации JSON.

    #Example.cs измените код для System.Text.Json настройки имен свойств и порядка выходных данных JSON из сериализации. Задайте имена свойств: FirstName значение first_name, LastName — last_name. Задайте порядок: Country, FirstName, LastName, Age. Укажите настраиваемые выходные данные сериализации.

    #Example.csВ запросе предоставляется ссылка на файл в качестве контекста в Copilot. Запрос можно настроить для вывода строки JSON с именами свойств и значениями, которые соответствуют вашим требованиям. Чтобы задать намерение и получить лучшие ответы с контекстом области, можно использовать такие функции чата, как команды косой черты, ссылки на файлы, методы или классы и потоки.

    В следующем выходных данных показан пример ответа Copilot Chat:

    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.
    

Когда Copilot возвращает блок кода, ответ включает параметры для копирования кода, вставки кода в новый файл или предварительного просмотра выходных данных кода.

Примечание.

Результаты могут отличаться от того, что показано в примерах ответов. Модели искусственного интеллекта являются недетерминированными, что означает, что они могут возвращать разные ответы при появлении одного и того же вопроса. Это может быть связано с дополнительным обучением и адаптацией с течением времени, языковым изменением, изменениями в контексте, такими как журнал чата и многое другое.

См. также