System.Text.Json でプロパティの名前と値をカスタマイズする方法
既定では、プロパティ名とディクショナリ キーは、大文字と小文字の区別を含め、JSON の出力では変更されません。 列挙型の値は数値として表されます。 また、プロパティは定義された順序でシリアル化されます。 ただし、次の方法でこれらの動作をカスタマイズできます:
- 特定のシリアル化されたプロパティ名と列挙型メンバー名を指定します。
- camelCase、snake_case、kebab-case などの組み込みの 名前付けポリシーを使用して、プロパティ名とディクショナリ キーを使用します。
- プロパティ名とディクショナリ キーにカスタム名前付けポリシーを使用する。
- 名前付けポリシーの有無にかかわらず、列挙型の値を文字列としてシリアル化する。
- シリアル化されたプロパティの順序の構成。
Note
Web の既定 の名前付けポリシーはキャメル ケースです。
ヒント
GitHub Copilot では、AI の支援を使用してプロパティの名前と値をカスタマイズできます。
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
はキャメル ケースではありません。
Note
組み込みの名前付けポリシーでは、サロゲート ペアである文字はサポートされていません。 詳細については、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
}
}
ディクショナリ キーの名前付けポリシーは、シリアル化にのみ適用されます。 ディクショナリを逆シリアル化すると、既定以外の名前付けポリシーに JsonSerializerOptions.DictionaryKeyPolicy 設定した場合でも、キーは JSON ファイルと一致します。
文字列としての列挙型
既定では、列挙型は数値としてシリアル化されます。 列挙型名を文字列としてシリアル化するには、JsonStringEnumConverter または JsonStringEnumConverter<TEnum> コンバーターを使用します。 ネイティブ AOT ランタイムでは、 JsonStringEnumConverter<TEnum> のみがサポートされます。
たとえば、列挙型を持つ次のクラスをシリアル化する必要があるとします。
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 属性を使用して注釈を付けます。
たとえば、カスタム メンバー名を持つ列挙型を持つ次のクラスをシリアル化する必要があるとします。
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
プロパティの既定値はゼロです。 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 文字列を出力できます。
次の例は、Copilot を使用して既存のコードを変更し、JSON にシリアル化するときにプロパティの名前と順序をカスタマイズする方法を示しています。
エディターで、次の 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
を使用して、JsonSerializer.Serialize
オブジェクトを JSON 文字列にシリアル化します。- 以下の JSON 文字列をコンソールに出力します。
{"FirstName":"John","LastName":"Doe","Age":30,"Country":"USA"}
Copilot Chat で次のプロンプトを入力してコードを変更し、JSON シリアル化出力の名前と順序をカスタマイズします。
#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 を利用しているため、想定外のことや間違いが起こる可能性があります。 詳細については、Copilot の FAQを参照してください。
Visual Studio での GitHub Copilot
関連項目
.NET