Json.NET - enumを文字列でシリアライズする
久しぶりにJson.NETのメモです。
Json.NETを使ってenum値をJSONに出力するとき、デフォルトでは数値になります。数値だとぱっと見わかりにくいので文字列で書き出したいときがあると思います。そんなときはStringEnumConverter
を使います。
使い方はたぶん2通り。
- プロパティなどに対して
JsonConverterAttribute
とセットで使う JsonSerializerSettings.Converters
に加える
あるプロパティのenumだけを対象にしたい場合はJsonConverterAttribute
、すべてのプロパティのenumを対象にしたい場合はJsonSerializerSettings.Converters
を使用するといった感じかなと思います。
enumを文字列でシリアライズ
どちらもコードで確認してみます。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; namespace ConsoleApp { // 適当なenum enum LogLevel { None, Info, Warn, Error, } // 適当なサンプル class Logger { public string Name { get; set; } public LogLevel MinLevel { get; set; } // JsonConverterAttributeでStringEnumConverterを指定する [JsonConverter(typeof(StringEnumConverter))] public LogLevel MaxLevel { get; set; } } class Program { static void Main(string[] args) { var settings = new JsonSerializerSettings { // ついでにプロパティ名をキャメルケースで出力 ContractResolver = new CamelCasePropertyNamesContractResolver(), // 見やすいようにインデントで整形 Formatting = Formatting.Indented, }; var logger = new Logger { Name = "test", MinLevel = LogLevel.Info, MaxLevel = LogLevel.Warn, }; // シリアライズして属性で指定したmaxLevelの値が文字列になっていることを確認 Console.WriteLine(JsonConvert.SerializeObject(logger, settings)); /* { "name": "test", "minLevel": 1, "maxLevel": "Warn" } */ // StringEnumConverterをConvertersに追加する // さらにenum文字列はキャメルケースに settings.Converters.Add(new StringEnumConverter { CamelCaseText = true }); // シリアライズしてminLevelとmaxLevelの値が文字列になっていることを確認 Console.WriteLine(JsonConvert.SerializeObject(logger, settings)); /* { "name": "test", "minLevel": "info", "maxLevel": "Warn" } */ // この場合、maxLevelの"Warn"はキャメルケースにならない // 属性のStringEnumConverterが優先される様子 // (今回のサンプルのように2重で設定するような使い方はしないと思うが) } } }
enumへデシリアライズ
enumへデシリアライズするときはJsonSerializerSettings
を使わなくても数値でも文字列でもいい感じに処理してくれます。
var json = @" { ""name"":""test"", ""minLevel"":""info"", ""maxLevel"":2 }"; var logger = JsonConvert.DeserializeObject<Logger>(json); Console.WriteLine(logger.Name); // test Console.WriteLine(logger.MinLevel); // Info Console.WriteLine(logger.MaxLevel); // Warn