前置き
Newtonsoft.json と System.Text.Json で、DBNull.Value と DateTime 型の値を変換する際の動作が異なっていました。
実行環境、コードは以下のような感じです。
といっても、両者の違いはメソッド名だけですが。
実行環境
- .NET Framework 4.8
- Newtonsoft.json 13.0.1
- System.Text.Json 5.0.2
Newtonsoft.json
dynamic data = new ExpandoObject();
data.nv = DBNull.Value;
data.dt = DateTime.Now;
var serialized = JsonConvert.SerializeObject(data);
var deserialized = JsonConvert.DeserializeObject<ExpandoObject>(r);
System.Text.Json
dynamic data = new ExpandoObject();
data.nv = DBNull.Value;
data.dt = DateTime.Now;
var serialized = JsonSerializer.Serialize(data);
var deserialized = JsonSerializer.Deserialize<ExpandoObject>(serialized);
結果
Newtonsoft.json
シリアライズ
{"nv":null,"dt":"2021-07-31T06:30:38.8041996+09:00"}
デシリアライズ
System.Text.Json
シリアライズ
{"nv":{},"dt":"2021-07-31T06:30:38.4280875+09:00"}
デシリアライズ
# | Newtonsoft.json | System.Text.Json |
---|---|---|
DBNull.Value | null | string 「"{}"」 |
DateTime | DateTime | string 「"JSONの日付フォーマット"」 |
シリアライズ時、DBNull.Value は Newtonsoft.json では null に出力され、
System.Text.Json では "{}"(空文字)で出力され、
DateTime は双方"JSONの日付フォーマット"で出力されました。
dynamic型でデシリアライズした際、System.Text.Json は System.Text.Json.JsonValueKind というクラスにラップされ、DateTime も文字列で返されます。
この辺は状況によってどちらが適切か分かれると思いますが、私は Newtonsoft.json の仕様の方が素直な感じがして賛成。
というか DateTime が文字列になってしまうのは辛いです。
マニアックな記事かもしれませんが、案件でハマったのでこの記事が誰かのお役に立てば幸いです。