67269


Pythonでは、JSONのシリアライズ・デシリアライズは以下のように行いますが  
C#ではどのようにすればよいですか？

[code]

    import json
    
    dict = {"test":{"test1":{"test2":"aaa"}}}
    dictDump = json.dumps(dict) #シリアライズ
    dictLoads = json.loads(dictDump) #デシリアライズ
    print(dictLoads["test"]["test1"]["test2"])
    
    #結果：aaa
    
[/code]

ちょっと調べた感じだと、C#とPythonの文法が違いすぎて理解できませんでした…。


CC BY-SA 4.0
2020-06-03T15:56:44.870
67264
2020-06-04T16:15:25.607
2020-06-03T16:59:11.903
3060
36446
question
c# json
C#でJSONのシリアライズ・デシリアライズをする方法


C#は他のモダンな言語よりもJSONに優しくないイメージがあります。  
コメントのアドバイスのように、クラスを理解してJSONの構造をパースすることがC#でJSONを扱う一般的な方法です。  
クラスを作成して[DataContractJsonSerializer](https://docs.microsoft.com/ja-
jp/dotnet/api/system.runtime.serialization.json.datacontractjsonserializer)を使うと.NET
Framework純正の環境のみでシリアライズ/デシリアライズできます。

サードパーティーのライブラリを使用可能な環境ならば[Json.NET](https://www.newtonsoft.com/json)を使う方法もあります。

ちなみに「なんで数行のJSON使うだけでクラス作らなきゃいけないんだ！」「私はただDictionaryをJSONにしたいだけなんだ…」というズボラな私は[DynamicJson](https://archive.codeplex.com/?p=dynamicjson)を使ったりもします。(サードパーティ製のライブラリです)  
nugetでライブラリをインストールする方法は割愛しますが、JSONとdynamicなオブジェクトを比較的短いコードで相互置換できます。  
以下はサンプルコードです。  
(入力補完とコンパイル時のチェックが効かず癖のあるdynamic型と匿名クラスを使いまくるとC#の良さをスポイルする気がしますが…)

参考資料: [C#でJSONを扱う方法まとめ](https://dev.classmethod.jp/articles/c-sharp-
json/#toc-19)

[code]

    using Codeplex.Data;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                // DynamicJson ver 1.2.0.0 で動作するコード
    
                // JsonをdynamicオブジェクトにParse
                dynamic j1 = DynamicJson.Parse(@"{""Greetings"":""Hello World!""}");
                Console.WriteLine(j1.Greetings);            // Hello World!
                dynamic n1 = DynamicJson.Parse(@"{""test"":{""test1"":{""test2"":""aaa""}}}");
                Console.WriteLine(n1.test.test1.test2);     // aaa
    
                // 匿名クラスをParse
                dynamic j2 = DynamicJson.Parse(DynamicJson.Serialize(new { Greetings = "Hello World!!" }));
                Console.WriteLine(j2.Greetings);            // Hello World!!
                dynamic n2 = DynamicJson.Parse(DynamicJson.Serialize(new { test = new { test1 = new { test2 = "aaa" } } }));
                Console.WriteLine(n2.test.test1.test2);     // aaa
    
                // 余談: DictionaryをParse
                dynamic j3 = DynamicJson.Parse(DynamicJson.Serialize(new Dictionary<string, string> { { "Greetings", "Hello World!!!" } }));
                Console.WriteLine(j3[0].Value);             // Hello World!!!
    
                Console.Read();
            }
        }
    }
    
[/code]


CC BY-SA 4.0
2020-06-04T00:07:33.357
67269
2020-06-04T00:07:33.357
9820
67264
answer


私は厳密に型指定をした `Json` を使う方を推奨します。  
プログラムはメンテナンスや、再利用できるかが大事だと思います。

利用するライブラリは 今なら `Newtonsoft.Json`(Json.NET) か `System.Text.Json` ですね。  
`System.Text.Json` は Microsoft 製で

[code]

    System.Text.Jsonは、主にパフォーマンス、セキュリティ、標準準拠に重点を置いています。
    
[/code]

という事です。

コード例は下記の通り： そんなにむつかしくないと思いますが・・。

test.json

[code]

    {
      "data": [{
        "type": "articles",
        "id": "1",
        "attributes": {
          "title": "JSON:API paints my bikeshed!",
          "body": "The shortest article. Ever.",
          "created": "2015-05-22T14:56:29.000Z",
          "updated": "2015-05-22T14:56:28.000Z"
        },
        "relationships": {
          "author": {
            "data": {"id": "42", "type": "people"}
          }
        }
      }],
      "included": [
        {
          "type": "people",
          "id": "42",
          "attributes": {
            "name": "John",
            "age": 80,
            "gender": "male"
          }
        }
      ]
    }
    
[/code]

コードの例

[code]

    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System.Text.Json;
    
    
            [Test]
            public void Test1()
            {
                // Newtonsoft.Json で クラスを定義せず 緩く使う場合
                string json = System.IO.File.ReadAllText("test.json");
    
                JObject o = JObject.Parse(json);
                string title = o["data"][0]["attributes"]["title"].Value<string>();
                DateTime? create = o["data"][0]["attributes"]["created"].Value<DateTime?>();
    
                Console.WriteLine(title);
                Console.WriteLine(create);
    
                // JSON:API paints my bikeshed!
                // 2015/05/22 14:56:28
            }
    
            // 使いたいところだけクラス定義します。
            public class TestJson
            {
                public Data[] Data { get; set; }
            }
            public class Data
            {
                public Attributes Attributes { get; set; }
            }
            public class Attributes
            {
                public string Title { get; set; }
                public DateTime? Created { get; set; }
            }
    
            [Test]
            public void Test2()
            {
                // Newtonsoft.Json を使う場合
                string json = System.IO.File.ReadAllText("test.json");
    
                var test = JsonConvert.DeserializeObject<TestJson>(json);
                string title = test.Data.FirstOrDefault()?.Attributes.Title;
                DateTime? create = test.Data.FirstOrDefault()?.Attributes.Created;
    
                Console.WriteLine(title);
                Console.WriteLine(create);
    
                // JSON:API paints my bikeshed!
                // 2015/05/22 14:56:28
            }
    
    
            [Test]
            public void Test3()
            {
                // System.Text.Json を使う場合
                string json = System.IO.File.ReadAllText("test.json");
    
                JsonSerializerOptions options = new JsonSerializerOptions()
                {
                    AllowTrailingCommas = true, // 配列の終わりの , を無視
                    PropertyNameCaseInsensitive = true, // 大文字小文字の違いを無視
                };
                var test = System.Text.Json.JsonSerializer.Deserialize<TestJson>(json, options);
                string title = test.Data.FirstOrDefault()?.Attributes.Title;
                DateTime? create = test.Data.FirstOrDefault()?.Attributes.Created;
    
                Console.WriteLine(title);
                Console.WriteLine(create);
    
                // JSON:API paints my bikeshed!
                // 2015/05/22 14:56:28
            }
    
    
[/code]


CC BY-SA 4.0
2020-06-04T16:15:25.607
67292
2020-06-04T16:15:25.607
18851
67264
answer