🙆‍♀️

デフォルト値つきのStringEnumConverter

2023/01/26に公開

あらまし

Newtonsoft.Jsonの中にあるStringEnumConverter、入力となるstringに対応するenumの値が存在しない場合に例外(JsonSerializationException)を吐きます。
これが嫌だったので、エラーとなった場合のデフォルト値を指定できるようにしました。

コード

class StringEnumConverterWithDefault : StringEnumConverter
{
    public StringEnumConverterWithDefault(object defaultValue)
    {
        DefaultValue = defaultValue;
    }

    public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
    {
        try
	{
	    return base.ReadJson(reader, objectType, existingValue, serializer);
	}
	catch (JsonSerializationException)
	{
	    return DefaultValue;
	}
    }

    private readonly object DefaultValue;
}

つかいかた

JsonConverterの引数2つ目以降がコンストラクタに渡されるみたいです。

enum HogeType
{
    Hoge,
    Huga,
    Piyo
}

class HogeClass
{
    [JsonProperty("hoge"), JsonConverter(typeof(StringEnumConverterWithDefault), HogeType.Piyo)]
    public HogeType Hoge
    { get; set; }
}

void Sample()
{
    var str = @"
{
    hoge: ""Hg""
}";
    var hoge = JsonConvert.DeserializeObject<HogeClass>(str);
    // hoge.hoge = HogeType.Piyo
}

やるべきなのか?

大した実装でもないですし、そもそもStringEnumConverterの使い方次第でできるのかなあと思ってましたが、案外見つからない実装だったので今回書きました。
ただ書いておいてなんですけど、見つからないってことは、あんまりやるべきではない実装なのかなとも思います。エラー握りつぶすわけですし。けど例外吐かれたところで、例えば1オブジェクト内に複数エラーがあっても1つしか検知できないし。

まあ選択肢はあって悪いことはないということで書きました。

Discussion