はじめに
昔、Newtonsoft.Json
があった(いまもある)。
Newtonsoft.Json
は、変換が柔軟な反面、パフォーマンス等が犠牲になっている。
しかし、常に柔軟さが必要なわけではない。
変換が厳密でいい場合に、Newtonsoft.Json
の機能は過剰であるから、よりパフォーマンスに優れたライブラリSystem.Text.Json
が作られた。
柔軟とはどういうことか?
例えば、Newtonsoft.Json
では、JSONのname
というキーがあったとき、これはC#のName
プロパティにデシリアライズできる。
System.Text.Json
ではデフォルトではこれはできない。
でも、JSONのキーはキャメルケースにしたいじゃん?
めんどくさい方法
C#のプロパティがどういう風にシリアライズされるか、は、プロパティごとに属性で定義できる。
public class Model
{
[JsonPropertyName("name")]
public string Name { get; set; }
}
これで自由にキー名をコントロールできる。
が、プロパティが多いと、全部にこれを指定するのはめんどくさすぎる。
簡単な方法
キャメルケースにしたい!と決まっている場合は、わざわざプロパティにJsonPropertyName
属性を指定せずとも、変換時の設定で一括でできる。
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
var json = JsonSerializer.Serialize(model, options);
プロパティについてるJsonPropertyName
属性が優先されるので、基本はキャメルケースだけどこれだけ別の指定…もできる。
もっと簡単な方法
Webでいい感じに使える、なんか、デフォルトの設定は無いの?→あります
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
var json = JsonSerializer.Serialize(model, options);
デフォルト設定としてJsonSerializerDefaults.Web
を指定すると、以下の設定がされる。
- シリアライズがキャメルケースになる
- デシリアライズ時にキーの大文字小文字が区別されなくなる
- デシリアライズ時に数値がダブルクオーテーションで囲まれていても良くなる
おまけ:自分がよく使う設定
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web)
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
//DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
//WriteIndented = true,
};
var json = JsonSerializer.Serialize(model, options);
- Web設定をベースにしつつ…
-
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
- 値のエスケープをゆるゆるにする。
- これをしないと、日本語もエスケープされて、読めなくなる。
{"name":"\u3053\u3093\u306B\u3061\u306F"}
- 指定するとこう↓
{"name":"こんにちは"}
-
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
- 値がnullになってるプロパティを、JSONに含めなくする。
- デフォルトでは
{"name":null}
みたいになるけど、これを付けておくと値がnullの場合は項目ごと無くなる。→{}
- 適宜つける。
-
WriteIndented = true
- 出力をインデントする。
- デバッグの時だけつける。