System.Text.JsonのJsonConverter
事の始まり
意外と何もしなくてもシリアライズ・デシリアライズ出来てしまうので、わざわざConverterを用意する機会がなかったりもする。
ただ、たまにException!とか言ってくるのでそんなときはJsonCoverterを書いてあげる必要がある。昔のStack Overflowを見ていると諦めて文字列でシリアライズしろよとかあって、チビリそうになるけど、今はJsonConverterがあるのよ。
FontFamilyでコケたので確認してみるとTypeConverterとかはあったりするので、string<->class変換は出来るけど、JsonConverterが設定されていないとJsonSerializorでは変換してくれないみたい。
サンプル
とりあえず簡単にJsonConverterを書いてみた。
public class FontFamilyJsonConverter : JsonConverter<Fontfamily>
{
public override FontFamily Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> new (reader.GetString());
public override void Write(Utf8JsonWriter writer, FontFamily value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.Source);
}
例外処理とかはないので自分でシリアライズ・デシリアライズするのが前提だけど、とりあえずは動く…と思う(私の環境だとWriteしか呼ばれてないので…)。
JsonConverterを知らないときは例外が発生するプロパティを[JsonIgnore]属性で対象外にし、別途シリアライズ・デシリアライズ用のプロパティを用意しようとしていたのですが、そんな必要はありませんでした。
使い方
使い方は以下の3つがある。
- JsonSerializerOptionsのCovertersに設定する
- プロパティに[JsonConverter]属性を設定する
- 型に[JsonConverter]属性を設定する
今回はすでにある型だったのと都度設定するのが面倒だったので2の方法にした。
[JsonConverter(typeof(FontFamilyJsonConverter))]
public FontFamily FontFamily { get => _fontFamily; set => SetProperty(ref _fontFamily, value); }
優先順位的には2 > 1 > 3みたいなので、後から変更できるようにしたいならプロパティには設定せずにJsonSerialiserOptionsに設定することになると思う。
コメント
コメントを投稿