다음을 통해 공유


System.Text.Json으로 속성 이름 및 값을 사용자 지정하는 방법

기본적으로 대/소문자를 비롯한 속성 이름 및 사전 키는 JSON 출력에서 변경되지 않습니다. 열거형 값은 숫자로 표시됩니다. 그리고 속성은 정의된 순서대로 직렬화됩니다. 그러나 다음을 통해 이러한 동작을 사용자 지정할 수 있습니다.

  • 직렬화된 특정 속성 및 열거형 멤버 이름을 지정합니다.
  • 속성 이름 및 사전 키에 대한 기본 제공 명명 정책(예: camelCase, 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
}

이 특성을 통해 설정된 속성 이름은 다음과 같은 특징이 있습니다.

기본 제공 명명 정책 사용

다음 표에서는 기본 제공 명명 정책과 속성 이름에 미치는 영향을 보여줍니다.

명명 정책 설명 원래 속성 이름 변환된 속성 이름
CamelCase 첫 번째 단어는 소문자로 시작합니다.
연속 단어는 대문자로 시작합니다.
TempCelsius tempCelsius
KebabCaseLower* 단어는 하이픈으로 구분됩니다.
모든 문자는 소문자입니다.
TempCelsius temp-celsius
KebabCaseUpper* 단어는 하이픈으로 구분됩니다.
모든 문자는 대문자입니다.
TempCelsius TEMP-CELSIUS
SnakeCaseLower* 단어는 밑줄로 구분됩니다.
모든 문자는 소문자입니다.
TempCelsius temp_celsius
SnakeCaseUpper* 단어는 밑줄로 구분됩니다.
모든 문자는 대문자입니다.
TempCelsius TEMP_CELSIUS

* .NET 8 이상 버전에서 사용할 수 있습니다.

다음 예제에서는 JsonSerializerOptions.PropertyNamingPolicy을(를) JsonNamingPolicy.CamelCase(으)로 설정하여 모든 JSON 속성 이름에 카멜 대/소문자를 사용하는 방법을 보여줍니다.

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/런타임 이슈 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
  }
}

사전 키에 대한 명명 정책은 serialization에만 적용됩니다. 사전을 역직렬화하는 경우 기본이 아닌 명명 정책으로 JsonSerializerOptions.DictionaryKeyPolicy을(를) 설정하더라도 키가 JSON 파일과 일치합니다.

문자열인 열거형

기본적으로 열거형은 숫자로 직렬화됩니다. 열거형 이름을 문자열로 직렬화하려면 JsonStringEnumConverter 또는 JsonStringEnumConverter<TEnum> 변환기를 사용합니다. JsonStringEnumConverter<TEnum>만 네이티브 AOT 런타임에서 지원됩니다.

예를 들어 열거형을 포함하는 다음 클래스를 직렬화해야 한다고 가정해 봅시다.

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

Summary가 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

열거형에 JsonConverterAttribute 주석을 추가하여 사용할 변환기를 지정할 수도 있습니다. 다음 예제에서는 JsonStringEnumConverter<TEnum> 특성을 사용하여 JsonConverterAttribute(.NET 8 이상 버전에서 사용 가능)를 지정하는 방법을 보여줍니다. 예를 들어 열거형을 포함하는 다음 클래스를 직렬화해야 한다고 가정해 봅시다.

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

사용자 지정 열거형 멤버 이름

.NET 9부터 문자열로 직렬화된 형식에 대해 개별 열거형 멤버의 이름을 사용자 지정할 수 있습니다. 열거형 멤버 이름을 사용자 지정하려면 JsonStringEnumMemberName 특성으로 주석을 추가합니다.

예를 들어 사용자 지정 멤버 이름을 가진 열거형이 있는 다음 클래스를 serialize해야 한다고 가정합니다.

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
}

다음 샘플 코드는 숫자 값 대신 열거형 이름을 직렬화합니다.

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

결과 JSON은 다음과 같습니다.

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Sky": "Partly cloudy"
}

원본 생성

원본 생성과 함께 변환기를 사용하려면 열거형 필드를 문자열로 직렬화를 참조하세요.

직렬화된 속성의 순서 구성

기본적으로 속성은 클래스에서 정의된 순서대로 직렬화됩니다. [JsonPropertyOrder] 특성을 사용하면 직렬화에서 JSON 출력의 속성 순서를 지정할 수 있습니다. Order 속성의 기본값은 0입니다. 속성을 기본값이 설정된 속성 뒤에 배치하려면 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를 사용하여 속성 이름 및 순서 사용자 지정

IDE에서 GitHub Copilot를 사용하여 직렬화된 속성의 이름과 순서를 사용자 지정하는 코드를 생성할 수 있습니다. 요구 사항에 맞는 속성 이름 및 값이 있는 JSON 문자열을 출력하도록 프롬프트를 사용자 지정할 수 있습니다.

다음 예제에서는 JSON으로 직렬화할 때 Copilot를 사용하여 기존 코드를 수정하여 속성 이름 및 순서를 사용자 지정하는 방법을 보여줍니다.

  1. 편집기에서 Example.cs 코드 파일에 다음 C# 예제 코드를 추가합니다. 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를 사용하여 JsonSerializer.Serialize 개체를 JSON 문자열로 직렬화합니다.
    • 콘솔에 다음 JSON 문자열을 인쇄합니다.
    {"FirstName":"John","LastName":"Doe","Age":30,"Country":"USA"}
    
  2. Copilot 채팅에서 다음 프롬프트를 입력하여 JSON serialization 출력의 이름과 순서를 사용자 지정하도록 코드를 수정합니다.

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

GitHub Copilot는 AI를 통해 구동되므로 예상치 못한 실수가 발생할 수 있습니다. 자세한 내용은 부조종사 FAQ참조하세요.

Visual Studio GitHub Copilot VS CodeGitHub Copilot를 대해 자세히 알아봅니다.

참고 항목