け日記

SIerから転職したWebアプリエンジニアが最近のITのキャッチアップに四苦八苦するブログ

Json.NETを使って任意のクラスやDictionary・Listにデシリアライズする

Json.NETを使って、JSONを任意のクラスとDictionary・Listにそれぞれデシリアライズしてみます。

www.nuget.org

任意のクラス(POCO)にデシリアライズする

例えばアプリケーションの設定ファイルのように静的な構造のJSONであれば、専用のPOCOにデシリアライズするほうが扱いやすいです。

{
  "Server": {
    "DomainName": "domain.name",
    "WebServerHostNames": [
      "web1.host.name",
      "web2.host.name"
    ],
    "DbServerHostNames": [
      "db1.host.name",
      "db2.host.name"
    ]
  },
  "Table": {
    "AccountTableName": "account-table" 
  }  
}

JSONのキー名とPOCOのプロパティ名が一致していれば、JsonConvert.DeserializeObject<Config>で上のJSONファイルをConfigクラスにデシリアライズできます。
ConfigとServerConfigのように、クラスは入れ子になっていてもOKです。

using Newtonsoft.Json;

public class Config
{
    public ServerConfig Server { get; set; }
    public TableConfig Table { get; set; }

    public class ServerConfig
    {
        public string DomainName { get; set; }
        public IList<string> WebServerHostNames { get; set; }
        public IList<string> DbServerHostNames { get; set; }
    }

    public class TableConfig
    {
        public string AccountTableName { get; set; }
    }
}

var config = JsonConvert.DeserializeObject<Config>(File.ReadAllText("config.json"));

DictionaryとListへデシリアライズする

例えば以下のマスタデータのようにキー("Kanto"や"Kinki")が動的に増減するJSONの場合は、DictionaryやListとして扱える方がソースコードに手をいれる必要が無いので都合が良いです。

{
  "Area": {
    "Kanto": [
      "Tokyo",
      "Chiba",
      "Kanagawa"
    ],
    "Kinki": [
      "Osaka",
      "Kyoto",
      "Nara"
    ] 
  }
}

POCOと同じく、JsonConvert.DeserializeObject<>でDictionaryやListへデシリアライズできます。
この場合も入れ子になっていても良く、Dictionary<string, Dictionary<string, List<string>>>でもOKです。

using Newtonsoft.Json;

var area =
    JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, List<string>>>>(
        File.ReadAllText("area.json"))["Area"];

foreach (var key in area.Keys)
{
    Console.WriteLine(key);
    foreach (var value in area[key])
    {
        Console.WriteLine(value);
    }
}