【C#/.NET8】System.Text.JsonでオブジェクトをJSONにシリアライズする方法

かつて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 クラスには、IdName という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.JsonSystem.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 を積極的に活用していきましょう!

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です