Udostępnij za pośrednictwem


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

Napiwek

Możesz użyć pomocy dotyczącej sztucznej inteligencji, aby dostosować nazwy i wartości właściwości za pomocą narzędzia GitHub Copilot.

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

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)

JsonConverterAttribute

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

Niestandardowe nazwy składowych wyliczenia

Począwszy od platformy .NET 9, można dostosować nazwy poszczególnych składowych wyliczenia dla typów, które są serializowane jako ciągi. Aby dostosować nazwę elementu członkowskiego wyliczenia, dodaj do niego adnotację za pomocą atrybutu 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 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,
  "Sky": "Partly cloudy"
}

Generowanie źródła

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

Dostosowywanie nazw właściwości i kolejności przy użyciu narzędzia Github Copilot

Możesz użyć narzędzia GitHub Copilot w środowisku IDE, aby wygenerować kod w celu dostosowania nazw i kolejności serializowanych właściwości.

Jeśli używasz programu Visual Studio 2022 w wersji 17.8 lub nowszej, możesz wypróbować oparte na sztucznej inteligencji narzędzie GitHub Copilot w programie Visual Studio , aby wygenerować kod używany System.Text.Json do dostosowywania nazw właściwości i kolejności w danych wyjściowych JSON z serializacji. Prześlij swoje pytanie jako monit w oknie czatu Copilot, jak w poniższym przykładzie. Możesz również przesyłać monity przy użyciu wbudowanego czatu w samym oknie edytora.

Uwaga

Narzędzie GitHub Copilot jest obsługiwane przez sztuczną inteligencję, więc możliwe są niespodzianki i błędy. Upewnij się, że zweryfikowano wygenerowany kod lub sugestie. Aby uzyskać więcej informacji na temat ogólnego użycia narzędzia GitHub Copilot, wpływu produktu, nadzoru ludzkiego i prywatności, zobacz GitHub Copilot — często zadawane pytania.

W poniższym przykładzie pokazano, jak używać narzędzia Copilot do modyfikowania istniejącego kodu w celu dostosowania nazw właściwości i kolejności podczas serializacji do formatu JSON.

  1. Dodaj następujący przykładowy kod w języku C# do pliku Example.cs kodu w edytorze. W programie Visual Studio możesz użyć projektu aplikacji konsolowej języka C#, aby wypróbować ten przykład.

    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 kod wykonuje następujące czynności:

    • Tworzy wystąpienie klasy i inicjuje Person jej właściwości wartościami.
    • Serializuje person obiekt w ciągu JSON przy użyciu polecenia JsonSerializer.Serialize.
    • Drukuje następujący ciąg JSON w konsoli:
    {"FirstName":"John","LastName":"Doe","Age":30,"Country":"USA"}
    
  2. W aplikacji Copilot Chat wprowadź następujący monit, aby zmodyfikować kod w celu dostosowania nazw i kolejności danych wyjściowych serializacji JSON.

    #Example.cs zmodyfikuj kod, aby użyć System.Text.Json polecenia , aby dostosować nazwy właściwości i kolejność danych wyjściowych JSON z serializacji. Ustaw nazwy właściwości: FirstName na first_name, LastName na last_name. Ustaw kolejność na: Country, FirstName, LastName, Age. Podaj dostosowane dane wyjściowe serializacji.

    #Example.cs w wierszu polecenia zawiera odwołanie do pliku jako kontekst dla Copilot. Możesz dostosować monit, aby wyświetlić ciąg JSON z nazwami właściwości i wartościami odpowiadającymi twoim wymaganiom. Aby ustawić intencję i uzyskać lepsze odpowiedzi z kontekstem o określonym zakresie, możesz użyć funkcji czatu, takich jak polecenia ukośnika, odwołania do plików, metod lub klas i wątków.

    W poniższych danych wyjściowych przedstawiono przykładową odpowiedź czatu copilot:

    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.
    

Gdy copilot zwraca blok kodu, odpowiedź zawiera opcje kopiowania kodu, wstawiania kodu do nowego pliku lub podglądu danych wyjściowych kodu.

Uwaga

Wyniki mogą się różnić od przedstawionych w przykładowych odpowiedziach. Modele sztucznej inteligencji są niedeterministyczne, co oznacza, że mogą zwracać różne odpowiedzi po zadawaniu tego samego pytania. Może to być spowodowane dodatkowym uczeniem się i adaptacją w czasie, odmianą języka, zmianami w kontekście, takimi jak historia czatów i nie tylko.

Zobacz też