プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2019/03/01

[C#] enum を文字列でシリアライズする

event_note2019/03/01 4:04

Newtonsoft.Json (Json.NET) で enum をシリアライズすると、デフォルトでは数値で出力されますが、これを文字列で出力する方法です。

環境

  • Visual Studio 2017
  • .NET Core 2.1

モデルと通常のシリアライズ

ここでは例として、以下のような Person クラスをシリアライズします。

enum Gender
{
    Male,
    Female,
    Unknown
}

enum Birthplace
{
    Japan
}

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Gender Gender { get; set; }
    public Birthplace Birthplace { get; set; }
}

特に何もせずにシリアライズしたら以下のような結果になります。
(見づらいのでインデントだけは設定しています。)

var json = JsonConvert.SerializeObject(
    new Person
    {
        Name = "hoge",
        Age = 30,
        Gender = Gender.Male,
        Birthplace = Birthplace.Japan
    },
    Formatting.Indented);
Console.WriteLine(json);

出力結果

{
  "Name": "hoge",
  "Age": 30,
  "Gender": 0,
  "Birthplace": 0
}

特定のプロパティのみ文字列でシリアライズ

文字列でシリアライズしたいプロパティに、以下の属性を付与します。

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    public Gender Gender { get; set; }
    public Birthplace Birthplace { get; set; }
}

出力結果

{
  "Name": "hoge",
  "Age": 30,
  "Gender": "Male",
  "Birthplace": 0
}

クラス内の enum 全てを文字列でシリアライズ

JsonConverter を設定すれば、enum 全てが文字列で出力されます。

var setting = new JsonSerializerSettings()
{
    Converters = new List<JsonConverter>(){
        new StringEnumConverter()
    },
    Formatting = Formatting.Indented
};

var json = JsonConvert.SerializeObject(
    new Person
    {
        Name = "hoge",
        Age = 30,
        Gender = Gender.Male,
        Birthplace = Birthplace.Japan
    },
    setting);
Console.WriteLine(json);

出力結果

{
  "Name": "hoge",
  "Age": 30,
  "Gender": "Male",
  "Birthplace": "Japan"
}

既定で enum は全て文字列でシリアライズするようにする

シリアライズする度に JsonConverter の設定をするのも面倒なので、そのような場合には既定値を設定できます。

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    Converters = new List<JsonConverter>(){
        new StringEnumConverter()
    },
    Formatting = Formatting.Indented
};

var json = JsonConvert.SerializeObject(
    new Person
    {
        Name = "hoge",
        Age = 30,
        Gender = Gender.Male,
        Birthplace = Birthplace.Japan
    });
Console.WriteLine(json);

出力結果

{
  "Name": "hoge",
  "Age": 30,
  "Gender": "Male",
  "Birthplace": "Japan"
}