LoginSignup
24
17

More than 3 years have passed since last update.

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

Posted at

はじめに

あるようで、なかったので。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"
  }
}

まとめ

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

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

参考

24
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
17