20200327のC#に関する記事は1件です。

今更ですが、C#でJsonを扱う

はじめに

あるようで、なかったので。Newtonsoft.Jsonの使い方です。DataContractJsonSerializerではありません。

準備

  • 「参照」を右クリック、「NuGet パッケージの管理...」

2020-03-18_141313.png

  • 「参照」タブから、「Newtonsoft.Json」を選択して、インストールする

2020-03-18_141424.png

基本

JsonConvert.SerializeObject() でシリアル化(オブジェクト → 文字列)、JsonConvert.DeserializeObject<T>() でデシリアル化(文字列 → オブジェクト)。

※サンプルなので、Formatting.Indented を指定して、JSONを見やすく改行して出力するようにしていますが、実際には無くても良いです。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    public DateTimeOffset CreatedDate { get; set; }
    public AccountRole Role { get; set; }
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // シリアライズ
        var account = new Account()
        {
            ID = 1,
            Name = @"hoge@example.com",
            IsActive = true,
            CreatedDate = DateTimeOffset.Now,
            Role = Account.AccountRole.Role1,
            Telephones = new List<string>()
            {
                "010-1111-2222",
                "020-2222-3333",
            },
        };

        var json = JsonConvert.SerializeObject(account, Formatting.Indented);
        Console.WriteLine(json);
        Console.WriteLine("\n---");

        // デシリアライズ
        var obj = JsonConvert.DeserializeObject<Account>(json);
        Console.WriteLine(string.Join("\n", typeof(Account).GetProperties().Select(info => $"{info.Name}: {info.GetValue(obj)}")));

        Console.ReadLine();
    }
}

出力

{
  "ID": 1,
  "Name": "hoge@example.com",
  "IsActive": true,
  "CreatedDate": "2020-03-18T14:29:30.1143602+09:00",
  "Role": 0,
  "Telephones": [
    "010-1111-2222",
    "020-2222-3333"
  ]
}

---
ID: 1
Name: hoge@example.com
IsActive: True
CreatedDate: 2020/03/18 14:28:21 +09:00
Role: Role1
Telephones: System.Collections.Generic.List`1[System.String]

enum のシリアライズ

C#では、enumは内部では数値なので、デフォルトでは数値で出力されてしまう。JsonConverterAttributeを使って、StringEnumConverterを指定すると、文字列にできる。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    public DateTimeOffset CreatedDate { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // シリアライズ
        var account = new Account()
        {
            ID = 1,
            Name = @"hoge@example.com",
            IsActive = true,
            CreatedDate = DateTimeOffset.Now,
            Role = Account.AccountRole.Role1,
            Telephones = new List<string>()
            {
                "010-1111-2222",
                "020-2222-3333",
            },
        };

        var json = JsonConvert.SerializeObject(account, Formatting.Indented);
        Console.WriteLine(json);

        Console.ReadLine();
    }
}

出力

{
  "ID": 1,
  "Name": "hoge@example.com",
  "IsActive": true,
  "CreatedDate": "2020-03-18T15:01:36.37789+09:00",
  "Role": "Role1",
  "Telephones": [
    "010-1111-2222",
    "020-2222-3333"
  ]
}

enumのデシリアライズ

なぜか、JsonConverterAttributeを付けていなくても、解釈できる。(しかし、シリアライズのことを考えると、JsonConverterAttributeを付けておいたほうが良いと思う)

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    public DateTimeOffset CreatedDate { get; set; }
    // [JsonConverter]付けない
    public AccountRole Role { get; set; }
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // デシリアライズ
        var json = $@"{{
""ID"": 999, 
""Name"": ""foo"", 
""IsActive"": true, 
""CreatedDate"": ""2020-01-02T03:04:05+09:00"", 
""Role"": ""Role2""
}}";

        var obj = JsonConvert.DeserializeObject<Account>(json);
        Console.WriteLine(string.Join("\n", typeof(Account).GetProperties().Select(info => $"{info.Name}: {info.GetValue(obj)}")));

        Console.ReadLine();
    }
}

出力

ID: 999
Name: foo
IsActive: True
CreatedDate: 2020/01/02 3:04:05 +09:00
Role: Role2
Telephones: System.Collections.Generic.List`1[System.String]

Jsonに enum に対応する属性がないと、enum は値型なので、null ではなく 0 に対応する値になってしまう。

class Program
{
    static void Main(string[] args)
    {
        // デシリアライズ
        var json = $@"{
""ID"": 999, 
""Name": ""foo"", 
""IsActive"": true, 
""CreatedDate"": ""2020-01-02T03:04:05+09:00""
}}";

        var obj = JsonConvert.DeserializeObject<Account>(json);
        Console.WriteLine(string.Join("\n", typeof(Account).GetProperties().Select(info => $"{info.Name}: {info.GetValue(obj)}")));

        Console.ReadLine();
    }
}

出力(Role0 に対応する Role1 になっている)

ID: 999
Name: foo
IsActive: True
CreatedDate: 2020/01/02 3:04:05 +09:00
Role: Role1
Telephones: System.Collections.Generic.List`1[System.String]

Json の enum に対応する値が null だと、例外を throw してしまう。

class Program
{
    static void Main(string[] args)
    {
        // デシリアライズ
        var json = $@"{
""ID"": 999, 
""Name"": ""foo"", 
""IsActive"": true, 
""CreatedDate"": ""2020-01-02T03:04:05+09:00"", 
""Role"": null
}}";

        var obj = JsonConvert.DeserializeObject<Account>(json);
        Console.WriteLine(string.Join("\n", typeof(Account).GetProperties().Select(info => $"{info.Name}: {info.GetValue(obj)}")));

        Console.ReadLine();
    }
}

2020-03-19_155612.png

DateTime のシリアライズ

一括で指定

JsonSerializerSettingsDateFormatHandlingプロパティでフォーマットを指定する。しかし、MicrosoftDateFormatIsoDateFormat(+0900というオフセットが付く、ISO 8601の書式)しか無い。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    public DateTimeOffset CreatedDate { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // シリアライズ
        var account = new Account()
        {
            ID = 1,
            Name = @"hoge@example.com",
            IsActive = true,
            CreatedDate = DateTimeOffset.Now,
            Role = Account.AccountRole.Role1,
            Telephones = new List<string>()
            {
                "010-1111-2222",
                "020-2222-3333",
            },
        };

        JsonSerializerSettings settings = new JsonSerializerSettings()
        {
            DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
            Formatting = Formatting.Indented,
        };
        var json = JsonConvert.SerializeObject(account, settings);
        Console.WriteLine(json);

        Console.ReadLine();
    }
}

出力

{
  "ID": 1,
  "Name": "hoge@example.com",
  "IsActive": true,
  "CreatedDate": "\/Date(1584586457933+0900)\/",
  "Role": "Role1",
  "Telephones": [
    "010-1111-2222",
    "020-2222-3333"
  ]
}

個別に指定

JsonConverterAttributeで指定する。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    [JsonConverter(typeof(IsoDateTimeConverter))]
    public DateTimeOffset CreatedDate { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // シリアライズ
        var account = new Account()
        {
            ID = 1,
            Name = @"hoge@example.com",
            IsActive = true,
            CreatedDate = DateTimeOffset.Now,
            Role = Account.AccountRole.Role1,
            Telephones = new List<string>()
            {
                "010-1111-2222",
                "020-2222-3333",
            },
        };

        var json = JsonConvert.SerializeObject(account, Formatting.Indented);
        Console.WriteLine(json);

        Console.ReadLine();
    }
}

出力

{
  "ID": 1,
  "Name": "hoge@example.com",
  "IsActive": true,
  "CreatedDate": "2020-03-19T14:46:17.3561825+09:00",
  "Role": "Role1",
  "Telephones": [
    "010-1111-2222",
    "020-2222-3333"
  ]
}

フォーマットを自分で指定

フォーマット指定ができるConverterが無いので、自分でそういうConverterを作るしかない。IsoDateTimeConverterDateTimeFormatプロパティでフォーマットを指定できるので、次のようにする。

DateTimeFormatConverter.cs
class DateTimeFormatConverter : IsoDateTimeConverter
{
     public DateTimeFormatConverter(string format)
     {
         DateTimeFormat = format;
     }
}

あとは、JsonConverterAttributeを付けるだけ。フォーマット文字列は第2引数で指定できる。ちなみに、フォーマット文字列は DateTime のものと同じです。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    [JsonConverter(typeof(DateTimeFormatConverter), "yyyy/MM/dd HH:mm:ss")]
    public DateTimeOffset CreatedDate { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // シリアライズ
        var account = new Account()
        {
            ID = 1,
            Name = @"hoge@example.com",
            IsActive = true,
            CreatedDate = DateTimeOffset.Now,
            Role = Account.AccountRole.Role1,
            Telephones = new List<string>()
            {
                "010-1111-2222",
                "020-2222-3333",
            },
        };

        var json = JsonConvert.SerializeObject(account, Formatting.Indented);
        Console.WriteLine(json);

        Console.ReadLine();
    }
}

出力

{
  "ID": 1,
  "Name": "hoge@example.com",
  "IsActive": true,
  "CreatedDate": "2020/03/19 14:25:18",
  "Role": "Role1",
  "Telephones": [
    "010-1111-2222",
    "020-2222-3333"
  ]
}

DateTimeのデシリアライズ

ちゃんとソースコードを見てないが、おそらく内部では DateTime.Parse() が使われているっぽいので、多少ルーズな書式でも読んでくれる。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    public DateTimeOffset CreatedDate { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // デシリアライズ
        var json = $@"{{
""ID"": 999, 
""Name"": ""foo"", 
""IsActive"": true, 
""CreatedDate"": ""2020/01/02 03:04:05"", 
""Role"": ""Role2""
}}";

        var obj = JsonConvert.DeserializeObject<Account>(json);
        Console.WriteLine(string.Join("\n", typeof(Account).GetProperties().Select(info => $"{info.Name}: {info.GetValue(obj)}")));

        Console.ReadLine();
    }
}

出力

ID: 999
Name: foo
IsActive: True
CreatedDate: 2020/01/02 3:04:05 +09:00
Role: Role2
Telephones: System.Collections.Generic.List`1[System.String]

ちゃんと書式を指定したい場合は、シリアライズで書いたように、DateTimeFormatConverter を自作して指定する。
※次のサンプルでは、書式を指定しないと、例外が出ます。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    [JsonConverter(typeof(DateTimeFormatConverter), "yyyy.MM.dd HH.mm.ss")]
    public DateTimeOffset CreatedDate { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // デシリアライズ
        var json = $@"{{
""ID"": 999, 
""Name"": ""foo"", 
""IsActive"": true, 
""CreatedDate"": ""2020.01.02 03.04.05"", 
""Role"": ""Role2""
}}";

        var obj = JsonConvert.DeserializeObject<Account>(json);
        Console.WriteLine(string.Join("\n", typeof(Account).GetProperties().Select(info => $"{info.Name}: {info.GetValue(obj)}")));

        Console.ReadLine();
    }
}

出力

ID: 999
Name: foo
IsActive: True
CreatedDate: 2020/01/02 3:04:05 +09:00
Role: Role2
Telephones: System.Collections.Generic.List`1[System.String]

ネストクラス

特に何も考える必要はない。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public class AccountAddress
    {
        public string Address1 { get; set; }
        public string Address2 { get; set; }
    }

    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    public DateTimeOffset CreatedDate { get; set; }
    public AccountRole Role { get; set; }
    public IList<string> Telephones { get; set; } = new List<string>();
    public AccountAddress Address { get; set; } = new AccountAddress();
}

class Program
{
    static void Main(string[] args)
    {
        // シリアライズ
        var account = new Account()
        {
            ID = 1,
            Name = @"hoge@example.com",
            IsActive = true,
            CreatedDate = DateTimeOffset.Now,
            Role = Account.AccountRole.Role1,
            Telephones = new List<string>()
            {
                "010-1111-2222",
                "020-2222-3333",
            },
            Address = new Account.AccountAddress()
            {
                 Address1 = "address1",
                 Address2 = "address2",
            },
        };

        var json = JsonConvert.SerializeObject(account, Formatting.Indented);
        Console.WriteLine(json);

        Console.ReadLine();
    }
}

出力

{
  "ID": 1,
  "Name": "hoge@example.com",
  "IsActive": true,
  "CreatedDate": "2020-03-19T11:27:59.1366704+09:00",
  "Role": "Role1",
  "Telephones": [
    "010-1111-2222",
    "020-2222-3333"
  ],
  "Address": {
    "Address1": "address1",
    "Address2": "address2"
  }
}

Jsonの属性名を指定する

一律ヘビ記法にする

シリアル化するときに、次のように、DefaultContractResolverSnakeCaseNamingStrategyを指定して、それをJsonSerializerSettingsに設定する。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    public DateTimeOffset CreatedDate { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // シリアライズ
        var account = new Account()
        {
            ID = 1,
            Name = @"hoge@example.com",
            IsActive = true,
            CreatedDate = DateTimeOffset.Now,
            Role = Account.AccountRole.Role1,
            Telephones = new List<string>()
            {
                "010-1111-2222",
                "020-2222-3333",
            },
        };

        var resolver = new DefaultContractResolver
        {
            NamingStrategy = new SnakeCaseNamingStrategy()
        };

        var json = JsonConvert.SerializeObject(account, new JsonSerializerSettings()
        {
            ContractResolver = resolver,
            Formatting = Formatting.Indented,
        });
        Console.WriteLine(json);

        Console.ReadLine();
    }
}

出力

{
  "id": 1,
  "name": "hoge@example.com",
  "is_active": true,
  "created_date": "2020-03-19T11:29:38.0498159+09:00",
  "role": "Role1",
  "telephones": [
    "010-1111-2222",
    "020-2222-3333"
  ]
}

個別に指定する

JsonPropertyAttributeの引数で指定する。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    [JsonProperty("user_id")]
    public int ID { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("active")]
    public bool IsActive { get; set; }
    [JsonProperty("created_date")]
    public DateTimeOffset CreatedDate { get; set; }
    [JsonProperty("role")]
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    [JsonProperty("telepohones")]
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // シリアライズ
        var account = new Account()
        {
            ID = 1,
            Name = @"hoge@example.com",
            IsActive = true,
            CreatedDate = DateTimeOffset.Now,
            Role = Account.AccountRole.Role1,
            Telephones = new List<string>()
            {
                "010-1111-2222",
                "020-2222-3333",
            },
        };

        var json = JsonConvert.SerializeObject(account, Formatting.Indented);
        Console.WriteLine(json);

        Console.ReadLine();
    }
}

出力

{
  "user_id": 1,
  "name": "hoge@example.com",
  "active": true,
  "created_date": "2020-03-19T11:34:57.7137179+09:00",
  "role": "Role1",
  "telephones": [
    "010-1111-2222",
    "020-2222-3333"
  ]
}

Jsonに含めない

JsonIgnoreAttributeを付ける。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    [JsonProperty("user_id")]
    public int ID { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("active")]
    public bool IsActive { get; set; }
    [JsonProperty("created_date")]
    public DateTimeOffset CreatedDate { get; set; }
    [JsonProperty("role")]
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    [JsonIgnore]
    public IList<string> Telephones { get; set; } = new List<string>();
}

class Program
{
    static void Main(string[] args)
    {
        // シリアライズ
        var account = new Account()
        {
            ID = 1,
            Name = @"hoge@example.com",
            IsActive = true,
            CreatedDate = DateTimeOffset.Now,
            Role = Account.AccountRole.Role1,
            Telephones = new List<string>()
            {
                "010-1111-2222",
                "020-2222-3333",
            },
        };

        var json = JsonConvert.SerializeObject(account, Formatting.Indented);
        Console.WriteLine(json);

        Console.ReadLine();
    }
}

出力

{
  "user_id": 1,
  "name": "hoge@example.com",
  "active": true,
  "created_date": "2020-03-19T11:40:14.0203605+09:00",
  "role": "Role1"
}

その他の属性を Dictionary にまとめる

JsonExtensionDataAttribteを付ける。
[JsonIgnore]が付いているプロパティでも、[JsonExtensionData]が付いているプロパティに含められる。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    [JsonProperty("user_id")]
    public int ID { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("active")]
    public bool IsActive { get; set; }
    [JsonProperty("created_date")]
    public DateTimeOffset CreatedDate { get; set; }
    [JsonProperty("role")]
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    [JsonProperty("telepohones")]
    public IList<string> Telephones { get; set; } = new List<string>();
    [JsonIgnore]
    public string Note { get; set; }
    [JsonExtensionData]
    public IDictionary<string, object> Extra { get; set; } = new Dictionary<string, object>();
}

class Program
{
    static void Main(string[] args)
    {
        // デシリアライズ
        var json = $@"{{
""user_id"": 999, 
""name"": ""foo"", 
""active"": true, 
""created_date"": ""2020/01/02 03:04:05"", 
""role"": ""Role2"", 
""note"": ""メモ"", 
""hoge"": ""fuga""
}}";

        var obj = JsonConvert.DeserializeObject<Account>(json);
        Console.WriteLine($"ID: {obj.ID}");
        Console.WriteLine($"Name: {obj.Name}");
        Console.WriteLine($"IsActive: {obj.IsActive}");
        Console.WriteLine($"CreatedDate: {obj.CreatedDate}");
        Console.WriteLine($"Role: {obj.Role}");
        Console.WriteLine($"Note: {obj.Note}");
        Console.WriteLine($"Extra: {string.Join(", ", obj.Extra.Select(pair => pair))}");

        Console.ReadLine();
    }
}

出力

ID: 999
Name: foo
IsActive: True
CreatedDate: 2020/01/02 3:04:05 +09:00
Role: Role2
Note:
Extra: [note, メモ], [hoge, fuga]

JsonをまとめてDictionaryに突っ込む

Jsonが key-value 形式になっていて読み込む場合、いちいちクラスを作るのではなく、Dictionary に入れたいときがある。その場合も、JsonConvert.DeserializeObject<T>TDictioanry<string, object> を指定すればいい。

class Program
{
    static void Main(string[] args)
    {
        // デシリアライズ
        var json = $@"{{
""user_id"": 999, 
""name"": ""foo"", 
""active"": true, 
""created_date"": ""2020/01/02 03:04:05"", 
""role"": ""Role2"",
""telephone"": [""010-1111-2222"", ""020-2222-3333""], 
""address"": {{""address1"":""住所1"", ""address2"":""住所2""}}
}}";

        var obj = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
        Console.WriteLine(string.Join("\n", obj.Select(pair => pair)));

        Console.ReadLine();
    }
}

出力

[user_id, 999]
[name, foo]
[active, True]
[created_date, 2020/01/02 03:04:05]
[role, Role2]
[telephone, [
  "010-1111-2222",
  "020-2222-3333"
]]
[address, {
  "address1": "住所1",
  "address2": "住所2"
}]

ストリームから直接読み書き

ファイルや外部のAPIからJsonを読み書きする場合、JsonSerializer を使うと、いちいち文字列を経由することなく、直接読み書きができる。

class Account
{
    public enum AccountRole { Role1, Role2, Role3 }

    public class AccountAddress
    {
        [JsonProperty("address1")]
        public string Address1 { get; set; }
        [JsonProperty("address2")]
        public string Address2 { get; set; }
    }

    [JsonProperty("user_id")]
    public int ID { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("active")]
    public bool IsActive { get; set; }
    [JsonProperty("created_date")]
    [JsonConverter(typeof(DateTimeFormatConverter), "yyyy/MM/dd HH:mm:ss")]
    public DateTimeOffset CreatedDate { get; set; }
    [JsonProperty("role")]
    [JsonConverter(typeof(StringEnumConverter))]
    public AccountRole Role { get; set; }
    [JsonProperty("telephones")]
    public IList<string> Telephones { get; set; } = new List<string>();
    [JsonProperty("address")]
    public AccountAddress Address { get; set; } = new AccountAddress();

    [JsonIgnore]
    public string Note { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var account = new Account()
        {
            ID = 1,
            Name = @"hoge@example.com",
            IsActive = true,
            CreatedDate = DateTimeOffset.Now,
            Role = Account.AccountRole.Role1,
            Address = new Account.AccountAddress()
            {
                Address1 = "address1",
                Address2 = "address2",
            },
            Telephones = new List<string>()
            {
                "010-1111-2222",
                "020-2222-3333",
            },
            Note = "ほげほげ",
        };

        // シリアライズ
        using (StreamWriter writer = File.CreateText(@"account.json"))
        {
            var serializer = new JsonSerializer();
            serializer.Serialize(writer, account);
        }

        // デシリアライズ
        using (StreamReader reader = File.OpenText(@"account.json"))
        {
            var serializer = new JsonSerializer();
            var obj = (Account) serializer.Deserialize(reader, typeof(Account));
            Console.WriteLine($"ID: {obj.ID}");
            Console.WriteLine($"Name: {obj.Name}");
            Console.WriteLine($"IsActive: {obj.IsActive}");
            Console.WriteLine($"CreatedDate: {obj.CreatedDate}");
            Console.WriteLine($"Role: {obj.Role}");
            Console.WriteLine($"Note: {obj.Note}");
            Console.WriteLine($"Telephones: {string.Join(", ", obj.Telephones)}");
            Console.WriteLine($"Addresses: {obj.Address.Address1}, {obj.Address.Address2}");
        }

        Console.ReadLine();
    }
}

出力

ID: 1
Name: hoge@example.com
IsActive: True
CreatedDate: 2020/03/27 12:11:03 +09:00
Role: Role1
Note:
Telephones: 010-1111-2222, 020-2222-3333
Addresses: address1, address2

json(見やすいように改行とインデントを入れていますが、実際は1行です)

{
  "user_id": 1,
  "name": "hoge@example.com",
  "active": true,
  "created_date": "2020/03/27 12:11:03",
  "role": "Role1",
  "telephones": ["010-1111-2222", "020-2222-3333"],
  "address": {
    "address1":"address1",
    "address2":"address2"
  }
}

まとめ

まだ不足しているパターンがありそうですが、そのときは追記します。

ここに載せた機能以外には、コンストラクタを使ってデシリアライズ、エラーハンドリング、デバッグ出力などがあります。この辺の機能はマニアックなので、書く予定ないですが。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む