記事内に広告が含まれています

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

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

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

環境

  • Visual Studio 2022
  • .NET 8

参考ドキュメント

C# で JSON をシリアル化する方法 - .NET
System.Text.Json 名前空間を使用して .NET で JSON にシリアル化する方法について説明します。 サンプル コードが含まれています。

前提

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

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

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

サンプルクラスの定義

まずJSONへのシリアライズとデシリアライズに使用するサンプルクラスを用意します。
JSON関係の属性を付与するため、usingSystem.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
.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),

    // (.NET 8以降)プロパティ名をスネークケースに変換
    PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,

    // (.NET 7以前)プロパティ名をスネークケースに変換するための自作ポリシーを適用
    //PropertyNamingPolicy = new SnakeCaseNamingPolicy(),

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

var person = new Person
{
    FullName = "田中太郎",
    Age = 20,
    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 には自作のポリシーを指定することもできます。
.NET 7以前の場合はスネークケースに変換するための名前付けポリシーが用意されていないので、ポリシーを自作して指定する必要があります。(詳細は後述)

WriteIndented

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

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

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

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

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

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

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

実行結果

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

(.NET 7 以前)カスタム名前付けポリシー

.NET 7 以前のバージョンを使用している場合は、スネークケースに変換するためには名前付けポリシーを自作する必要があります。

参考までにポリシーの実装を紹介します。

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 メソッドをオーバーライドすることで作成することができます。

ここでは正規表現を用いてパスカルケースのプロパティ名をスネークケースに変換しています。

おすすめ書籍

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

著:出井 秀行
¥3,536 (2024/09/29 10:21時点 | Amazon調べ)
\楽天ポイント4倍セール!/
楽天市場
\ポイント5%還元!/
Yahooショッピング
C#
hiranote

コメント

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