4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[C#]JSONデシリアライズ化に便利なサイトの紹介と注意事項

Posted at

主題

JSONファイルからデシリアライズ後のデータクラス定義を自動生成してくれるサイトの紹介と、
実際に使ってみた際に気づいた点を説明。

json2csharp.com

利用手順

1.JSONファイルの内容をコピペする。
2.Convertをクリックすると、C#のクラス宣言コードが生成される。

なお、JSONファイル内でキー名が定義されていない要素は、"Root"や”MyArray”などの適当な名称が割り振られるため、
適切な名称にリネームする必要がある。
スクリーンショット 2020-08-02 11.31.18.png

注意事項

Convert後の先頭行にはJSON.NETライブラリによるデシリアライズするサンプルコードも一緒に出力されるが、
これは正常に動作しない場合がある。

##上手く行かない例

[
    {
        "frames": [
            {
                "Delay": 0,
                "Index": 0
            }
        ],
        "Name": ""
    },
    {
        "frames": [
            {
                "Delay": 0,
                "Index": 3
            }
        ],
        "Name": ""
    }
]

上記のように、JSONの最上位要素がコレクションや配列になっている場合、当該サイトでコンバートすると、以下の結果となる。


    Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); //デシリアライズコード
    public class Frame    {
        public int Delay { get; set; } 
        public int Index { get; set; } 
    }

    public class MyArray    {
        public List<Frame> frames { get; set; } 
        public string Name { get; set; } 
    }

    public class Root    {
        public List<MyArray> MyArray { get; set; } 
    }

一見すると、デシリアライズが上手く行そうだが、実際に実行すると以下例外発生する。

JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Root' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

エラー内容を見ると、配列オブジェクトを単一オブジェクトでデシリアライズしようとしたので怒られている様子。
JSONファイルの構造を変えない場合は、以下のコードでデシリアライズ可能。

List<MyArray> root = JsonConvert.DeserializeObject<List<MyArray>>(json);

##上手く行く例

{
    "MyArray": [
        {
            "frames": [
                {
                    "Delay": 0,
                    "Index": 0
                }
            ],
            "Name": ""
        },
        {
            "frames": [
                {
                    "Delay": 0,
                    "Index": 3
                }
            ],
            "Name": ""
        }
    ]
}

先ほどと違い、JSONの最上位要素が{}で括られている、つまり単一オブジェクトの場合は先ほどの例と同じコンバート結果になり、
デシリアライズもサンプルコードのままで上手くいく。


    Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); //デシリアライズコード
    Console.WriteLine("Count="+ myDeserializedClass.MyArray.Count.ToString());

    public class Frame    {
        public int Delay { get; set; } 
        public int Index { get; set; } 
    }

    public class MyArray    {
        public List<Frame> frames { get; set; } 
        public string Name { get; set; } 
    }

    public class Root    {
        public List<MyArray> MyArray { get; set; } 
    }
Count=2
4
5
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
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?