Jak dostosować nazwy i wartości właściwości za pomocą polecenia System.Text.Json

Domyślnie nazwy właściwości i klucze słownika są niezmienione w danych wyjściowych JSON, w tym wielkości liter. Wartości wyliczenia są reprezentowane jako liczby. Właściwości są serializowane w kolejności, w której są zdefiniowane. Można jednak dostosować te zachowania, wykonując następujące czynności:

  • Określanie określonych nazw właściwości serializowanych.
  • Używanie wbudowanych zasad nazewnictwa, takich jak camelCase, snake_case lub kebab-case, dla nazw właściwości i kluczy słownika.
  • Używanie niestandardowych zasad nazewnictwa dla nazw właściwości i kluczy słownika.
  • Serializowanie wartości wyliczenia jako ciągów z zasadami nazewnictwa lub bez.
  • Konfigurowanie kolejności właściwości serializowanych.

Uwaga

Domyślne zasady nazewnictwa sieci Web to przypadek camel.

W przypadku innych scenariuszy, które wymagają specjalnej obsługi nazw i wartości właściwości JSON, można zaimplementować konwertery niestandardowe.

Dostosowywanie poszczególnych nazw właściwości

Aby ustawić nazwę poszczególnych właściwości, użyj atrybutu [JsonPropertyName].

Oto przykładowy typ serializacji i wynikowy kod JSON:

public class WeatherForecastWithPropertyNameAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyNameAttribute
    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
}

Nazwa właściwości ustawiona przez ten atrybut:

Korzystanie z wbudowanych zasad nazewnictwa

W poniższej tabeli przedstawiono wbudowane zasady nazewnictwa i ich wpływ na nazwy właściwości.

Zasady nazewnictwa opis Oryginalna nazwa właściwości Przekonwertowana nazwa właściwości
CamelCase Pierwsze słowo zaczyna się od małego znaku.
Kolejne wyrazy zaczynają się od wielkiej litery.
TempCelsius tempCelsius
KebabCaseLower* Wyrazy są oddzielone łącznikami.
Wszystkie znaki są małymi literami.
TempCelsius temp-celsius
KebabCaseUpper* Wyrazy są oddzielone łącznikami.
Wszystkie znaki są wielkimi literami.
TempCelsius TEMP-CELSIUS
SnakeCaseLower* Wyrazy są oddzielone podkreśleniami.
Wszystkie znaki są małymi literami.
TempCelsius temp_celsius
SnakeCaseUpper* Wyrazy są oddzielone podkreśleniami.
Wszystkie znaki są wielkimi literami.
TempCelsius TEMP_CELSIUS

* Dostępne na platformie .NET 8 i nowszych wersjach.

W poniższym przykładzie pokazano, jak używać przypadku camel dla wszystkich nazw właściwości JSON, ustawiając wartość JsonSerializerOptions.PropertyNamingPolicy na 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)

Oto przykładowa klasa do serializacji i danych wyjściowych JSON:

public class WeatherForecastWithPropertyNameAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyNameAttribute
    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
}

Zasady nazewnictwa:

  • Dotyczy serializacji i deserializacji.
  • Jest zastępowany przez [JsonPropertyName] atrybuty. Dlatego nazwa Wind właściwości JSON w przykładzie nie jest przypadkiem camel.

Uwaga

Żadna z wbudowanych zasad nazewnictwa nie obsługuje listów, które są parami zastępczymi. Aby uzyskać więcej informacji, zobacz dotnet/runtime issue 90352 (problem 90352).

Używanie niestandardowych zasad nazewnictwa właściwości JSON

Aby użyć niestandardowych zasad nazewnictwa właściwości JSON, utwórz klasę, która pochodzi z JsonNamingPolicy metody i zastąpi metodę ConvertName , jak pokazano w poniższym przykładzie:

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

Następnie ustaw JsonSerializerOptions.PropertyNamingPolicy właściwość na wystąpienie klasy zasad nazewnictwa:

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)

Oto przykładowa klasa do serializacji i danych wyjściowych JSON:

public class WeatherForecastWithPropertyNameAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyNameAttribute
    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
}

Zasady nazewnictwa właściwości JSON:

  • Dotyczy serializacji i deserializacji.
  • Jest zastępowany przez [JsonPropertyName] atrybuty. Dlatego nazwa Wind właściwości JSON w przykładzie nie jest wielkimi literami.

Używanie zasad nazewnictwa dla kluczy słownika

Jeśli właściwość obiektu do serializacji jest typu Dictionary<string,TValue>, string klucze można przekonwertować przy użyciu zasad nazewnictwa, takich jak przypadek camel. W tym celu ustaw JsonSerializerOptions.DictionaryKeyPolicy odpowiednie zasady nazewnictwa. W poniższym przykładzie użyto CamelCase zasad nazewnictwa:

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)

Serializowanie obiektu ze słownikiem o nazwie TemperatureRanges zawierającej pary klucz-wartość i "HotMinTemp", 40 spowodowałoby wyświetlenie danych wyjściowych "ColdMinTemp", 20 JSON w następujący przykład:

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

Zasady nazewnictwa dla kluczy słownika mają zastosowanie tylko do serializacji. W przypadku deserializacji słownika klucze będą zgodne z plikiem JSON, nawet jeśli ustawiono JsonSerializerOptions.DictionaryKeyPolicy zasady nazewnictwa inne niż domyślne.

Wyliczenia jako ciągi

Domyślnie wyliczenia są serializowane jako liczby. Aby serializować nazwy wyliczenia jako ciągi, użyj konwertera JsonStringEnumConverter lub JsonStringEnumConverter<TEnum> . Tylko JsonStringEnumConverter<TEnum> środowisko uruchomieniowe natywnej usługi AOT jest obsługiwane.

Domyślnie wyliczenia są serializowane jako liczby. Aby serializować nazwy wyliczenia jako ciągi, użyj konwertera JsonStringEnumConverter .

Załóżmy na przykład, że musisz serializować następującą klasę, która ma wyliczenie:

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

Jeśli parametr Podsumowanie to Hot, domyślnie serializowany kod JSON ma wartość liczbową 3:

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

Poniższy przykładowy kod serializuje nazwy wyliczenia zamiast wartości liczbowych i konwertuje nazwy na przypadek camel:

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)

Wynikowy kod JSON wygląda następująco:

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

Wbudowany JsonStringEnumConverter element może również deserializować wartości ciągów. Działa z określonymi zasadami nazewnictwa lub bez niej. W poniższym przykładzie pokazano deserializacji przy użyciu polecenia 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)

Możesz również określić konwerter do użycia, dodając adnotacje do wyliczenia za pomocą polecenia JsonConverterAttribute. W poniższym przykładzie pokazano, jak określić JsonStringEnumConverter<TEnum> wartość (dostępną na platformie .NET 8 i nowszych wersjach) przy użyciu atrybutu JsonConverterAttribute . Załóżmy na przykład, że musisz serializować następującą klasę, która ma wyliczenie:

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
}

Poniższy przykładowy kod serializuje nazwy wyliczenia zamiast wartości liczbowych:

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

Wynikowy kod JSON wygląda następująco:

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

Aby użyć konwertera z generowaniem źródła, zobacz Serializowanie pól wyliczenia jako ciągów.

Konfigurowanie kolejności właściwości serializowanych

Domyślnie właściwości są serializowane w kolejności, w której są zdefiniowane w swojej klasie. Atrybut [JsonPropertyOrder] umożliwia określenie kolejności właściwości w danych wyjściowych JSON z serializacji. Wartość domyślna Order właściwości to zero. Ustaw Order wartość na liczbę dodatnią, aby umieścić właściwość po tych, które mają wartość domyślną. Order Ujemne pozycje właściwości przed tymi, które mają wartość domyślną. Właściwości są zapisywane w kolejności od najniższej Order wartości do najwyższej. Oto przykład:

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

Zobacz też