System.Text.Json でプロパティの名前と値をカスタマイズする方法
既定では、プロパティ名とディクショナリ キーは、大文字と小文字の区別を含め、JSON の出力では変更されません。 列挙型の値は数値として表されます。 この記事では、次の方法について学習します。
- 個々のプロパティ名をカスタマイズする
- すべてのプロパティ名をキャメル ケースに変換する
- カスタム プロパティの名前付けポリシーを実装する
- ディクショナリ キーをキャメル ケースに変換する
- 列挙型を文字列およびキャメル ケースに変換する
- シリアル化されるプロパティの順序を構成する
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
}
この属性によって設定されるプロパティ名は:
- シリアル化と逆シリアル化の両方の方向に適用されます。
- プロパティの名前付けポリシーよりも優先されます。
- パラメーター化されたコンストラクターのパラメーター名の一致には影響しません。
すべての JSON プロパティ名にキャメル ケースを使用する
すべての JSON プロパティ名にキャメル ケースを使用するには、次の例に示すように、JsonSerializerOptions.PropertyNamingPolicy を 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)
シリアル化するクラスと 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
はキャメル ケースではありません。
カスタム 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
キーをキャメル ケースに変換できます。 これを行うには、次の例に示すように、DictionaryKeyPolicy を JsonNamingPolicy.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
}
}
ディクショナリ キーに対するキャメル ケースの名前付けポリシーは、シリアル化にのみ適用されます。 ディクショナリを逆シリアル化すると、DictionaryKeyPolicy
に JsonNamingPolicy.CamelCase
を指定した場合でも、キーが JSON ファイルと一致します。
文字列としての列挙型
既定では、列挙型は数値としてシリアル化されます。 列挙型名を文字列としてシリアル化するには、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 名前付けポリシーが指定されていても機能します。 その他の名前付けポリシー (スネーク ケースなど) はサポートされていません。 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)
スネーク ケース名前付けポリシーを使用しながら逆シリアル化をサポートするカスタム コンバーター コードについては、「列挙型文字列値の逆シリアル化をサポートする」を参照してください。
シリアル化されるプロパティの順序を構成する
[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"
//}