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":"u6C38u91CEu82BDu90C1","age":21,"height":163},{"name":"u672Cu7530u7FFC","age":28,"height":166},{"name":"u6238u7530u6075u68A8u9999","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:CSharptest.json", jsonString);
デシリアライズ
var people = JsonSerializer.Deserialize<List<Person>>(jsonString);
var jsonString = File.ReadAllText(@"D:CSharptest.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);
}