Udostępnij za pomocą


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ślonej serializowanej właściwości i nazw składowych wyliczenia.
  • Używanie wbudowanej polityki 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 wyliczeniowych jako ciągów znaków, z polityką nazewnictwa lub bez niej.
  • 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.

Dostosuj poszczególne nazwy 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 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
}

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

Zasady nazewnictwa:

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

Uwaga

Żadna z wbudowanych zasad nazewnictwa nie obsługuje znakó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 dziedziczy po JsonNamingPolicy i zastępuje 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 właściwość JsonSerializerOptions.PropertyNamingPolicy na instancję swojej 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 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
}

Zasady nadawania nazw właściwościom JSON:

  • Dotyczy serializacji i deserializacji.
  • Jest zastępowany przez [JsonPropertyName] atrybuty. Dlatego nazwa właściwości JSON Wind w przykładzie nie jest pisana 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. Aby to zrobić, ustaw JsonSerializerOptions.DictionaryKeyPolicy zgodnie z preferowaną przez siebie polityką nazewnictwa. W poniższym przykładzie użyto CamelCase polityki 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 z nazwą TemperatureRanges, która zawiera pary klucz-wartość "ColdMinTemp", 20 i "HotMinTemp", 40, spowodowałoby utworzenie danych wyjściowych JSON jak w poniższym przykładzie:

{
  "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 łańcuchy znaków

Domyślnie wyliczenia są serializowane jako liczby. Aby serializować nazwy wyliczeń jako ciągi znaków, użyj konwertera JsonStringEnumConverter lub JsonStringEnumConverter<TEnum>. Tylko JsonStringEnumConverter<TEnum> jest obsługiwane przez środowisko uruchomieniowe Native AOT.

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

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 deserializację przy użyciu 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

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

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 elementów wyliczeń 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"
}

Niestandardowe nazwy składowych wyliczenia

Począwszy od .NET 9, można dostosować nazwy poszczególnych elementów wyliczenia dla typów, które są serializowane jako ciągi znaków. Aby dostosować nazwę elementu wyliczenia, oznacz go atrybutem JsonStringEnumMemberName.

Załóżmy na przykład, że musisz serializować następującą klasę zawierającą wyliczenie o niestandardowej nazwie składowej:

public class WeatherForecastWithEnumCustomName
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public CloudCover? Sky { get; set; }
}

[JsonConverter(typeof(JsonStringEnumConverter))]
public enum CloudCover
{
    Clear,
    [JsonStringEnumMemberName("Partly cloudy")]
    Partial,
    Overcast
}

Poniższy przykładowy kod serializuje nazwy elementów wyliczeń 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,
  "Sky": "Partly cloudy"
}

Generowanie źródła

Aby użyć konwertera z generowaniem kodu źródłowego, 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ą. Ujemna wartość Order ustawia właściwość 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"
//}

Dostosowywanie sposobu serializacji nazw właściwości za pomocą sztucznej inteligencji

Możesz użyć narzędzi sztucznej inteligencji, takich jak GitHub Copilot, aby zastosować wzorce zmian w sposobie serializacji kodu.

Załóżmy, że deklaracja klasy ma właściwości zgodne z PascalCasing, a standard JSON dla twojego projektu to snake_casing. Możesz użyć sztucznej inteligencji, aby dodać niezbędne atrybuty [JsonPropertyName] do każdej właściwości w klasie. Możesz użyć narzędzia Copilot, aby wprowadzić te zmiany za pomocą monitu czatu w następujący sposób:

Update #ClassName:
when the property name contains more than one word,
change the serialized property name to use underscores between words.
Use built-in serialization attributes.

Oto bardziej kompletna wersja przykładu, która zawiera prostą klasę.

Take this C# class:
public class WeatherForecast
{
    public DateTime Date { get; set; }
    public int TemperatureC { get; set; }
    public int TemperatureF { get; set; }
    public string? Summary { get; set; }
    public int WindSpeed { get; set; }
}
When the property name contains more than one word,
change the serialized property name to use underscores between words.
Use built-in serialization attributes.

Przed ich zastosowaniem przejrzyj sugestie Copilota.

Aby uzyskać więcej informacji na temat narzędzia GitHub Copilot, zobacz Często zadawane pytania dotyczące usługi GitHub.

Zobacz też