System.Text.Json でプロパティの名前と値をカスタマイズする方法
既定では、プロパティ名とディクショナリ キーは、大文字と小文字の区別を含め、JSON の出力では変更されません。 列挙型の値は数値として表されます。 また、プロパティは定義された順序でシリアル化されます。 ただし、次の方法でこれらの動作をカスタマイズできます:
- 特定のシリアル化されたプロパティ名の指定。
- camelCase、snake_case、kebab-case などの組み込みの 名前付けポリシーを使用して、プロパティ名とディクショナリ キーを使用します。
- プロパティ名とディクショナリ キーにカスタム名前付けポリシーを使用する。
- 名前付けポリシーの有無にかかわらず、列挙型の値を文字列としてシリアル化する。
- シリアル化されたプロパティの順序の構成。
Note
Web の既定 の名前付けポリシーはキャメル ケースです。
JSON プロパティの名前と値の特別な処理を必要とするその他のシナリオでは、カスタム コンバーターを実装することができます。
個々のプロパティ名をカスタマイズする
個々のプロパティの名前を設定するには、[JsonPropertyName] 属性を使用します。
シリアル化する型と、結果として得られる 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
}
この属性によって設定されるプロパティ名は:
- シリアル化と逆シリアル化の両方の方向に適用されます。
- プロパティの名前付けポリシーよりも優先されます。
- パラメーター化されたコンストラクターのパラメーター名の一致には影響しません。
組み込みの名前付けポリシーを使用する
次の表に、組み込みの名前付けポリシーと、それらがプロパティ名にどのように影響するかを示します。
名前付けポリシー | 説明 | 元のプロパティ名 | 変換されたプロパティ名 |
---|---|---|---|
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 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
}
名前付けポリシー:
- シリアル化と逆シリアル化に適用されます。
[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 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
}
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)
キーと値のペア "ColdMinTemp", 20
および "HotMinTemp", 40
を持つ TemperatureRanges
という名前のディクショナリを使用してオブジェクトをシリアル化すると、次の例のような 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> のみがサポートされます。
既定では、列挙型は数値としてシリアル化されます。 列挙型名を文字列としてシリアル化するには、 JsonStringEnumConverter コンバーターを使用します。
たとえば、列挙型を持つ次のクラスをシリアル化する必要があるとします。
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> (.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"
}
ソース生成でコンバーターを使用するには、「列挙型フィールドを文字列としてシリアル化する」を参照してください。
シリアル化されるプロパティの順序を構成する
既定では、プロパティはクラスで定義されている順序でシリアル化されます。 [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"
//}
関連項目
.NET
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示