【C#】System.Text.Jsonの基本的な使い方

C#

標準で搭載されているSystem.Text.Json名前空間のJsonSerializerクラスを使って、JSONのシリアライズやデシリアライズを行う方法についてまとめました。

スポンサーリンク

環境

  • Visual Studio 2022
  • .NET 6

参考ドキュメント

C# を使用して JSON をシリアル化および逆シリアル化する方法 - .NET
System.Text.Json 名前空間を使用して .NET 内で JSON のシリアル化と逆シリアル化を行う方法について学習します。 サンプル コードが含まれています。

前提

JSONシリアライズとは、C#のオブジェクトをJSON形式の文字列に変換(シリアル化)することで、JsonSerializerクラスのSerializeメソッドを使用します。

一方JSONデシリアライズはシリアライズの逆で、JSON形式の文字列をC#のオブジェクトに変換(非シリアル化)することを指し、JsonSerializerクラスのDeserializeメソッドを使用します。

以下では、コンソールアプリを用いてこれらの仕組みを説明します。

サンプルクラスの定義

まずJSONへのシリアライズとデシリアライズに使用するサンプルクラスを用意します。
JSON関係の属性を付与するため、usingに「System.Text.Json.Serialization」を追加しています。

using System.Text.Json.Serialization;

internal class Person
{
    [JsonPropertyName("Name")]
    public string? FullName { get; set; }

    public int Age { get; set; }

    public string? FavoriteThings { get; set; }

    [JsonIgnore]
    public string? Memo { get; set; }
}

プロパティに付与している属性について説明します。

JsonPropertyName属性

シリアライズまたはデシリアライズ時に、プロパティ名を指定した名前に変換することができます。
後に説明する名前付けポリシーよりも優先して適用されます。

JsonIgnore属性

通常はすべてのpublicプロパティがJSON化されますが、この属性を付与するとそのプロパティを対象から除外することができます。

さらに細かく条件を指定して除外することもできるので、気になる方はドキュメントを確認してみてください。

System.Text.Json でプロパティを無視する方法
.NET の System.Text.Json を使用してシリアル化するときにプロパティを無視する方法について説明します。

JSONのシリアライズ・デシリアライズ

Program.csにてシリアライズとデシリアライズを行います。

using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;

// オプション設定
var options = new JsonSerializerOptions
{
    // 日本語を変換するためのエンコード設定
    Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),

    // プロパティ名をキャメルケースに変換
    //PropertyNamingPolicy = JsonNamingPolicy.CamelCase,

    // プロパティ名をスネークケースに変換(自作ポリシーの適用)
    PropertyNamingPolicy = new SnakeCaseNamingPolicy(),

    // インデントを付ける
    WriteIndented = true
};

var person = new Person
{
    FullName = "田中太郎",
    Age = 30,
    FavoriteThings = "読書",
    Memo = "こんにちは"
};

// シリアライズ
var jsonString = JsonSerializer.Serialize(person, options);
Console.WriteLine(jsonString);

// デシリアライズ
var person2 = JsonSerializer.Deserialize<Person>(jsonString, options);
Console.WriteLine($"{person2?.FullName} {person2?.Age} {person2?.FavoriteThings}");

最初にJsonSerializerのオプション設定を行っています。よく使いそうなオプションについて説明します。

Encoder

日本語がUnicodeエスケープシーケンスに変換(例:あ → \u3042)されるのを防ぐため、日本語が含まれる場合は必ず「JavaScriptEncoder.Create(UnicodeRanges.All)」と指定します。

PropertyNamingPolicy

名前付けポリシーを指定することができます。
例えば「JsonNamingPolicy.CamelCase」を指定すると、シリアライズ時に全てのプロパティ名をキャメルケースに変換してくれます。

また、PropertyNamingPolicyには自作のポリシーを指定することもできます。
今回はスネークケースに変換するための名前付けポリシーを自作したのでそれを指定しています。

WriteIndented

trueにするとJSON出力時にインデントが付与されて見やすくなります。

他にも色々なオプションがあるので、こちらも詳しくはドキュメントをチェックしてみてください。

System.Text.Json でプロパティの名前と値をカスタマイズする方法
.NET で System.Text.Json を使用してシリアル化するときに、プロパティの名前と値をカスタマイズする方法について説明します。

JSONのシリアライズ・デシリアライズ

シリアライズするには、JSON化したいデータとオプションをJsonSerializerクラスのSerializeメソッドの引数に指定します。

デシリアライズは、Deserialize<T>メソッドの引数にJSONデータとオプションを指定します。

<T>にはバインドしたい型を指定します。今回はPersonクラスを指定しました。

実行結果

名前付けポリシーやJsonPropertyName属性によって、シリアライズ時にプロパティ名が指定通りに変更されていることが確認できます。

(参考)カスタム名前付けポリシー

参考として、スネークケースに変換するためのカスタム名前付けポリシーをご紹介します。

using System.Text.Json;
using System.Text.RegularExpressions;

/// <summary>
/// スネークケース命名ポリシー
/// </summary>
internal class SnakeCaseNamingPolicy : JsonNamingPolicy
{
    /// <summary>
    /// プロパティ名をスネークケースに変換する
    /// </summary>
    /// <param name="name">変換前のプロパティ名</param>
    /// <returns>変換後のプロパティ名</returns>
    public override string ConvertName(string name)
    {
        var pattern = "[a-z][A-Z]";
        MatchEvaluator evaluator = m => m.Groups[0].Value[0] + "_" + m.Groups[0].Value[1];
        return Regex.Replace(name, pattern, evaluator).ToLower();
    }
}

カスタムポリシーはJsonNamingPolicy抽象クラスを継承して、ConvertNameメソッドをオーバーライドすることで作成することができます。

ここでは正規表現を用いてパスカルケースのプロパティ名をスネークケースに変換しています。
変換処理については以下のサイトを参考にさせていただきました。

https://blog.hmatoba.net/Article/102

おすすめ書籍

JsonSerializerの基本的な使い方などが紹介されています。

著:出井 秀行
¥3,428 (2023/05/30 22:18時点 | Amazon調べ)

コメント

タイトルとURLをコピーしました