かつて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
を積極的に活用していきましょう!
コメントを残す