[Json.NET] C#でJSONを扱う

# はじめに
C#でJSONを簡単に扱えることができるライブラリ「Json.NET」を紹介します。

# Json.NETとは
JSON（JavaScript Object Notation） はテキストベースのデータフォーマットです。通信データや設定ファイルなどで使用され、プログラミング言語に問わず扱うことができるとされています。

C# は静的型付け言語（4.0から動的型付け言語）です。.NET Framework の標準ライブラリ [DataContractJsonSerializer](https://docs.microsoft.com/ja-jp/dotnet/api/system.runtime.serialization.json.datacontractjsonserializer?view=netframework-3.5) では、オブジェクトからJSON（シリアライズ）、JSONからオブジェクト（デシリアライズ）に変換するためには、型が特定されている必要があります。

Json.NETでは、型が特定されているJSON、特定されていないJSONを扱うことができます。

# Json.NETのインストール
下記のサイトで、`Newtonsoft.Json.dll` をダウンロードして、プロジェクトに参照設定を行います。

Json.NET
https://www.newtonsoft.com/json
https://github.com/JamesNK/Newtonsoft.Json/releases

## 型の定義
### オブジェクト
```C#:型
[JsonObject]
class Class1
{
    [JsonProperty("key1")]
    public string Key1 { get; set; }

    [JsonProperty("key2")]
    public int Key2 { get; set; }

    [JsonProperty("key3")]
    public bool Key3 { get; set; }

    [JsonProperty("key4")]
    public DateTime Key4 { get; set; }
}
```

### 配列
```C#:型
[JsonObject]
class Class2
{
    [JsonProperty("key1")]
    public List<string> Key1 { get; set; }
}
```

### オブジェクト配列
```C#:型
[JsonObject]
class Class3
{
    [JsonProperty("key1")]
    public List<SubClass3> Key1 { get; set; }
}

[JsonObject]
class SubClass3
{
    [JsonProperty("key2")]
    public string Key2 { get; set; }
}
```

## シリアライズ
### オブジェクト
```C#:型が特定されている
Class1 jsonObj = new Class1
{
    Key1 = "value1",
    Key2 = 2,
    Key3 = true,
    Key4 = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc)
};
string jsonStr = JsonConvert.SerializeObject(jsonObj, Formatting.None);
Console.WriteLine("{0}", jsonStr); // {"key1":"value1","key2":2,"key3":true,"key4":"2013-01-20T00:00:00Z"}
```

```C#:型が特定されていない
JObject jsonObj = new JObject
{
    ["key1"] = "value1",
    ["key2"] = 2,
    ["key3"] = true,
    ["key4"] = "2013-01-20T00:00:00Z",
};
string jsonStr = JsonConvert.SerializeObject(jsonObj, Formatting.None);
Console.WriteLine("{0}", jsonStr); // {"key1":"value","key2":2,"key3":true,"key4":"2013-01-20T00:00:00Z"}
```

### 配列
```C#:型が特定されている
Class2 jsonObj = new Class2
{
    Key1 = new List<string>
    {
        "value1",
        "value2"
    }
};
string jsonStr = JsonConvert.SerializeObject(jsonObj, Formatting.None);
Console.WriteLine("{0}", jsonStr); // {"key1":["value1","value2"]}
```

```C#:型が特定されていない
JObject jsonObj = new JObject
{
    ["key1"] = new JArray
    {
        "value1",
        "value2"
    }
};
string jsonStr = JsonConvert.SerializeObject(jsonObj, Formatting.None);
Console.WriteLine("{0}", jsonStr); // {"key1":["value1","value2"]}
```

### オブジェクト配列
```C#:型が特定されている
Class3 jsonObj = new Class3
{
    Key1 = new List<SubClass3>
    {
        new SubClass3
        {
            Key2 = "value1"
        },
        new SubClass3
        {
            Key2 = "value2"
        }
    }
};
string jsonStr = JsonConvert.SerializeObject(jsonObj, Formatting.None);
Console.WriteLine("{0}", jsonStr); // {"key1":[{"key2":"value1"},{"key2":"value2"}]}
```

```C#:型が特定されていない
JObject jsonObj = new JObject
{
    ["key1"] = new JArray
    {
        new JObject
        {
            ["key2"] = "value1"
        },
        new JObject
        {
            ["key2"] = "value2"
        }
    }
};
string jsonStr = JsonConvert.SerializeObject(jsonObj, Formatting.None);
Console.WriteLine("{0}", jsonStr); // {"key1":[{"key2":"value1"},{"key2":"value2"}]}
```

## デシリアライズ
### オブジェクト
```C#:型が特定されている
string jsonStr = @"{key1: 'value1', key2: 2, key3: true, key4: '2013-01-20T00:00:00Z'}";
Class1 jsonObj = JsonConvert.DeserializeObject<Class1>(jsonStr);
Console.WriteLine("Key1={0}", jsonObj.Key1); // value1
Console.WriteLine("Key2={0}", jsonObj.Key2); // 2
Console.WriteLine("Key3={0}", jsonObj.Key3); // true
Console.WriteLine("Key4={0}", jsonObj.Key4); // 2013-01-20T00:00:00Z
```

```C#:型が特定されていない
string jsonStr = @"{key1: 'value1', key2: 2, key3: true, key4: '2013-01-20T00:00:00Z'}";
JObject jsonObj = JObject.Parse(jsonStr);
Console.WriteLine("Key1={0}", jsonObj["key1"]); // value1
Console.WriteLine("Key2={0}", jsonObj["key2"]); // 2
Console.WriteLine("Key3={0}", jsonObj["key3"]); // true
Console.WriteLine("Key4={0}", jsonObj["key4"]); // 2013-01-20T00:00:00Z
```

### 配列
```C#:型が特定されている
string jsonStr = @"{key1: ['value1', 'value2']}";
Class2 jsonObj = JsonConvert.DeserializeObject<Class2>(jsonStr);
foreach (string key1Item in jsonObj.Key1)
{
    Console.WriteLine("Key1={0}", key1Item); // value1, value2
}
```

```C#:型が特定されていない
string jsonStr = @"{key1: ['value1', 'value2']}";
JObject jsonObj = JObject.Parse(jsonStr);
foreach (string key1Item in jsonObj["key1"])
{
    Console.WriteLine("Key1={0}", key1Item); // value1, value2
}
```

### オブジェクト配列
```C#:型が特定されている
string jsonStr = @"{key1: [{'key2': 'value1'}, {'key2': 'value2'}]}";
Class3 jsonObj = JsonConvert.DeserializeObject<Class3>(jsonStr);
foreach (SubClass3 key1Item in jsonObj.Key1)
{
    Console.WriteLine("key2={0}", key1Item.Key2); // value1, value2
}
```

```C#:型が特定されていない
string jsonStr = @"{key1: [{'key2': 'value1'}, {'key2': 'value2'}]}";
JObject jsonObj = JObject.Parse(jsonStr);
foreach (JObject key1Item in jsonObj["key1"])
{
    Console.WriteLine("key2={0}", key1Item["key2"]); // value1, value2
}
```

以上です。