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

2019/07/02

[C#] JSON へのシリアライズ時に数値を文字列で出力する

event_note2019/07/02 1:12

C# で JSON にシリアライズする場合、数値を文字列として出力する方法です。
JSON のパーサーは Newtonsoft.json (JSON.NET) を使用します。

概要

Newtonsoft.json (JSON.NET) で Enum を文字列で出力したい場合、StringEnumConverter を使用します。

数値を文字列で出力したい場合も同様にコンバーターを使用しますが、デフォルトでは用意されていないため、自作します。

他に良い方法があったら教えてください。

環境

  • Visual Studio 2017
  • .NET Core 2.2

サンプル

例えば、以下のようなクラスを JSON でシリアライズしたとします。

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
var person = new Person()
{
    Name = "Hoge",
    Age = 20
};
var json = JsonConvert.SerializeObject(person);
Console.WriteLine(json);

デフォルトでは

以下のように、int は数値で出力されます(わかりやすくするため整形しています)。

{
    "Name" : "Hoge",
    "Age" : 20
}

これを訳あって文字列で出力したい場合は以下のようにします。

コンバーターの作成

コンバーターの例

数値を文字列に変換する StringNumberConverter を以下のように作成します。

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class StringNumberConverter<T> : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jt = JToken.ReadFrom(reader);

        return jt.Value<T>();
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof(T).Equals(objectType);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value.ToString());
    }
}

Attribute の指定

Person クラスのプロパティに Attribute を指定します。

public class Person
{
    public string Name { get; set; }
    [JsonConverter(typeof(StringNumberConverter<int>))]
    public int Age { get; set; }
}

シリアライズの結果

この状態でシリアライズすると、以下のように数値が文字列で出力されます。

{
    "Name" : "Hoge",
    "Age" : "20"
}