C#

【C#】System.Text.Jsonの使い方

System.Text.Jsonは .NET Core 3.0以降では標準で用意されています。
それより以前のバージョンでは下記の場合にパッケージをインストールすることで利用することが可能です。

  • .NET Standard 2.0 以降のバージョン
  • .NET Framework 4.7.2 以降のバージョン
  • .NET Core 2.0、2.1、および 2.2

【検証環境】.NET 5.0

クラスの定義

サンプルコードで使うPersonクラスを定義します。

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

class Person
{
    [JsonProperty("name")]   
    public string Name { get; set; }
    [JsonProperty("age")]
    public int Age { get; set; }
    [JsonProperty("height")]
    public int Height { get; set; }

    public static Person GetPerson()
    {
        return new Person()
        {
            Name = "本田翼",
            Age = 28,
            Height = 166,
        };
    }
    public static List<Person> GetPepople()
    {
        return new List<Person>()
        {
            new Person()
            {
                Name = "永野芽郁",
                Age = 21,
                Height = 163,
            },
            new Person()
            {
                Name = "本田翼",
                Age = 28,
                Height = 166,
            },
            new Person()
            {
                Name = "戸田恵梨香",
                Age = 32,
                Height = 164,
            },
        };
    }
}

使い方

基本的にはJson.NETと似たような雰囲気で使えるようです。

https://docs.microsoft.com/ja-jp/dotnet/standard/serialization/system-text-json-overview

シリアライズ

var jsonString = JsonSerializer.Serialize(Person.GetPerson());
Console.WriteLine(jsonString);
//[{"name":"\u6C38\u91CE\u82BD\u90C1","age":21,"height":163},{"name":"\u672C\u7530\u7FFC","age":28,"height":166},{"name":"\u6238\u7530\u6075\u68A8\u9999","age":32,"height":164}]

上記の結果の様に、日本語の場合は文字化けしてしまいます。
JsonSerializerOptionsを生成して、第2引数に渡す必要があります。また、インデントを整形するためにWriteIndentedをtrueにします。

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

var options = new JsonSerializerOptions
{
    //日本語の場合の文字化け防止
    Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
  //インデント整形
  WriteIndented = true,
};
var jsonString = JsonSerializer.Serialize(Person.GetPerson(), options);
Console.WriteLine(jsonString);
//[
//  {
//    "name": "永野芽郁",
//    "age": 21,
//    "height": 163
//  },
//  {
//    "name": "本田翼",
//    "age": 28,
//    "height": 166
//  },
//  {
//    "name": "戸田恵梨香",
//    "age": 32,
//    "height": 164
//  }
//]

本稿では実行結果を見やすくするためにWriteIndentedをtrueにしてJSONのインデントを整形しますが、実際に業務等で扱う場合はパフォーマンスの低下を防ぐため規定値のfalseにしてください。

File.WriteAllText(@"D:\CSharp\test.json", jsonString);

デシリアライズ

var people = JsonSerializer.Deserialize<List<Person>>(jsonString);
var jsonString = File.ReadAllText(@"D:\CSharp\test.json");
var people = JsonSerializer.Deserialize<List<Person>>(jsonString);

個々のプロパティの設定

一部のプロパティを出力しない

既定ではすべてのプロパティがシリアル化されますが、一部だけシリアル化させないためにはJsonIgnore属性を使用します。
PersonクラスのHeightプロパティに設定してみると、出力されなくなりました。

class Person
{
    [JsonPropertyName("name")]
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]  //追加
    public string Name { get; set; }
    [JsonPropertyName("age")]
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]  //追加
    public int Age { get; set; }
    [JsonPropertyName("height")]
    <span class="fz-14px">[JsonIgnore]</span>  //追加
    public int Height { get; set; }
}

//[
//  {
//    "name": "永野芽郁",
//    "age": 21
//  },
//  {
//    "name": "本田翼",
//    "age": 28
//  },
//  {
//    "name": "戸田恵梨香",
//    "age": 32
//  }
//]

JsonIgnore属性のConditionプロパティを設定することによって、条件付き除外を指定できます。

Always(規定値) プロパティを常に出力しない
Never グローバル設定に関係なく、常にシリアル化および逆シリアル化する
WhenWritingDefault プロパティが規定値の場合、シリアル化しない
WhenwritingNull プロパティが参照型またはnull許容型で値がnullの場合、シリアル化しない

名前付けポリシー

本稿では最初にモデルのプロパティにJsonPropertyName属性を設定してプロパティ名を小文字で設定しています。
プロパティ数が多いと面倒になりますが、名前付きポリシーを利用すると一つ一つのプロパティに小文字でJsonPropertyName属性を設定する必要が無くなります。(※JsonPropertyName属性の方が優先されます。)

//名前付きポリシークラスの定義
public class LowerCaseNamingPolicy : JsonNamingPolicy
{
    public override string ConvertName(string name) => name.ToLower();
}

static void Main(string[] args)
{
    var options = new JsonSerializerOptions
    {
        //プロパティ名ポリシー設定
        PropertyNamingPolicy = new LowerCaseNamingPolicy(),
        //日本語の場合の文字化け防止
        Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
        //インデント整形
        WriteIndented = true,
    };
    var jsonString = JsonSerializer.Serialize(Person.GetPerson(), options);
    Console.WriteLine(jsonString);
}

エンジニアの転職ならこれ!

【第二新卒向け】マイナビジョブ20's

マイナビジョブ20'sは、20代・第二新卒・既卒向けの転職エージェントです。

▼こんな方におすすめ
・はじめて転職しようと思っている
・転職できるだけのスキルが自分にあるか不安
・手厚いサポートを受けたい

【フリーランス向け】安心保障と豊富な案件紹介 Midworks

Midworksは豊富な案件と「フリーランス」と「正社員」の良いとこ取りをした働き方を実現する手厚い保障が特徴です。

▼こんな方におすすめ
・現在正社員でフリーランスになろうか悩んでいる
・フリーランスとして働いているが、先行きが不安がある  (安定的な案件確保や保障など)
・自分の市場価値を知りたい、見合った案件で参画したい
・今後のキャリアビジョンを踏まえて案件を選びたい

【未経験向け】自宅で現役エンジニアから学べる TechAcademy

テックアカデミーは、現役エンジニアから学べるオンラインに特化したプログラミングスクールです。
講師は全員、通過率10%の選考に合格した現役エンジニア。
確かなスキルをもとに受講生をマンツーマンサポートします。


▼こんな方におすすめ
・自宅にいながらオンライン完結で勉強できる
・受講生に1人ずつ現役エンジニアのパーソナルメンターが専属でつく
・チャットで質問すればすぐに回答が返ってくる
・オリジナルサービスやオリジナルアプリなどの開発までサポート