かつてC#でJSONのシリアライズ(オブジェクトをJSON形式の文字列に変換)を行う際、多くの開発者が利用していたのが Newtonsoft.Json(通称Json.NET)でした。しかし、.NET Core 3.0以降、そして現在の.NET 8では、マイクロソフト公式の System.Text.Json が標準ライブラリとして提供されており、追加のNuGetパッケージなしで高速かつ効率的にJSONの操作が可能となっています。
本記事では、System.Text.Json を使った基本的なシリアライズの方法から、プロパティ名のカスタマイズ、配列やネストされたオブジェクトのシリアライズまで、順を追って丁寧に解説していきます。
基本のシリアライズ:クラスをJSONに変換する
まずは非常にシンプルなクラスを用意してみましょう。
public record Person
{
public int Id { get; set; }
public string Name { get; set; }
}この Person クラスには、Id と Name という2つのプロパティだけが定義されています。これをインスタンス化し、JSON文字列にシリアライズしてみます。
using System.Text.Json;
var p1 = new Person { Id = 1, Name = "Taro" };
var jsonP1 = JsonSerializer.Serialize<Person>(p1);
Console.WriteLine(jsonP1);出力されるJSON文字列は以下の通りです:
{"Id":1,"Name":"Taro"}とても簡単ですね!JsonSerializer.Serialize メソッドにオブジェクトを渡すだけで、自動的にプロパティがJSON形式に変換されます。
プロパティ名をカスタマイズする:小文字に変えたい場合
JavaScriptとやりとりする場合など、JSONのプロパティ名を小文字から始めたいケースは多いでしょう。その場合、System.Text.Json.Serialization.JsonPropertyName 属性を使えば、出力されるプロパティ名を指定できます。
以下のように Person クラスを修正します:
using System.Text.Json.Serialization;
public record Person
{
[JsonPropertyName("id")]
public int Id { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
}
そして、次のようにシリアライズしてみましょう。
var p4 = new Person { Id = 4, Name = "Shiro" };
var jsonP4 = JsonSerializer.Serialize<Person>(p4);
Console.WriteLine(jsonP4);出力:
{"id":4,"name":"Shiro"}このように、C# の PascalCase(先頭大文字)を JSON の camelCase(先頭小文字)に柔軟に変換できます。
配列のシリアライズ
次は、複数の Person インスタンスを配列にしてシリアライズする例です。
var p2 = new Person { Id = 2, Name = "Jiro" };
var people = new Person[] { p1, p2 };
var jsonArray = JsonSerializer.Serialize<Person[]>(people);
Console.WriteLine(jsonArray);出力:
[{"Id":1,"Name":"Taro"},{"Id":2,"Name":"Jiro"}]このように、配列やリストをそのまま渡すだけで、複数のオブジェクトが正しくJSONの配列として出力されます。
ネストされたオブジェクトのシリアライズ
もちろん、オブジェクトの中にさらにオブジェクトや配列を含む場合も、System.Text.Json はしっかり対応しています。
例えば、Group というクラスを用意して、その中に Person[] を持たせるケースを考えてみましょう。
public record Group
{
public int GroupId { get; set; }
public Person[] People { get; set; }
}Group インスタンスを作成してみます。
var group = new Group
{
GroupId = 1,
People = new Person[] { p1, p2 }
};
var jsonGroup = JsonSerializer.Serialize<Group>(group);
Console.WriteLine(jsonGroup);出力:
{"GroupId":1,"People":[{"Id":1,"Name":"Taro"},{"Id":2,"Name":"Jiro"}]}プロパティ名をカスタマイズしたい場合は、先ほどと同じく JsonPropertyName を使えばOKです。
その他の便利な設定オプション
JsonSerializerOptions を使うと、シリアライズ時の挙動をさらにカスタマイズできます。
例:camelCaseに自動変換したい場合
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true // 整形して見やすく
};
var jsonIndented = JsonSerializer.Serialize(p1, options);
Console.WriteLine(jsonIndented);出力:
{
"id": 1,
"name": "Taro"
}このように、JsonSerializerOptions を使えば、クラス側に [JsonPropertyName] をつけなくても一括でネーミングポリシーを変更できます。
Newtonsoft.Json との違い
| 機能 | Newtonsoft.Json | System.Text.Json |
|---|---|---|
| 標準ライブラリ | ×(別途NuGet必要) | ○(.NET Core 3.0〜) |
| パフォーマンス | 普通 | 高速 |
| カスタマイズ性 | 非常に高い | 徐々に充実中 |
| JSON Schema対応 | ○ | × |
| デフォルトでの循環参照検出 | × | ○(例外で検出) |
.NET 8 を使用しているなら、特に理由がなければ System.Text.Json を積極的に使っていくのが良いでしょう。
まとめ
.NET 8以降では、標準ライブラリである System.Text.Json を使うことで、高速かつシンプルにJSONのシリアライズが可能です。
JsonSerializer.Serializeを使えば簡単に変換できるJsonPropertyName属性でプロパティ名を自由に指定可能- 配列、ネストされたオブジェクトも問題なし
JsonSerializerOptionsでネーミングポリシーや整形出力も可能
普段の業務や個人開発においても、外部ライブラリに依存せずに軽量な構成を実現できます。今後は System.Text.Json を積極的に活用していきましょう!
