web-dev-qa-db-ja.com

Json.NetはList <object>を処理できますか?

List<User> list = LoadUsers();

JObject json = new JObject();

json["users"] = new JValue(list);

動作していないようですか?

エラー:

Could not determine JSON object type for type System.Collections.Generic.List`1
23
mrblah

JValueには、文字列、int、ブール値、日付などの単純な値のみを含めることができます。複雑なオブジェクトを含めることはできません。私はあなたが本当に欲しいのはこれだと思います:

_List<User> list = LoadUsers();

JObject json = new JObject();

json["users"] = JToken.FromObject(list);
_

上記は、Userオブジェクトのリストをユーザーを表すJArrayJObjectsに変換し、それを新しいusersJObjectプロパティに割り当てます。これは、_json["users"]_のTypeプロパティを調べて、Arrayであることを確認することで確認できます。

対照的に、この質問に対する別の回答で提案されたようにjson["users"] = new JValue(JsonConvert.SerializeObject(list))を実行すると(現在は削除されています)、おそらく、探している結果が得られないでしょう。このアプローチでは、ユーザーのリストを文字列にシリアル化し、そこから単純なJValueを作成してから、JValueusersJObjectプロパティに割り当てます。 _json["users"]_のTypeプロパティを調べると、それがStringであることがわかります。これが意味するのは、後でjson.ToString()を使用してJObjectをJSONに変換しようとすると、おそらく期待するJSONの代わりに二重シリアル化された出力が得られるということです。

違いを説明するための短いデモを次に示します。

_class Program
{
    static void Main(string[] args)
    {
        List<User> list = new List<User>
        {
            new User { Id = 1, Username = "john.smith" },
            new User { Id = 5, Username = "steve.martin" }
        };

        JObject json = new JObject();

        json["users"] = JToken.FromObject(list);
        Console.WriteLine("First approach (" + json["users"].Type + "):");
        Console.WriteLine();
        Console.WriteLine(json.ToString(Formatting.Indented));

        Console.WriteLine();
        Console.WriteLine(new string('-', 30));
        Console.WriteLine();

        json["users"] = new JValue(JsonConvert.SerializeObject(list));
        Console.WriteLine("Second approach (" + json["users"].Type + "):");
        Console.WriteLine();
        Console.WriteLine(json.ToString(Formatting.Indented));
    }

    class User
    {
        public int Id { get; set; }
        public string Username { get; set; }
    }
}
_

出力:

_First approach (Array):

{
  "users": [
    {
      "Id": 1,
      "Username": "john.smith"
    },
    {
      "Id": 5,
      "Username": "steve.martin"
    }
  ]
}

------------------------------

Second approach (String):

{
  "users": "[{\"Id\":1,\"Username\":\"john.smith\"},{\"Id\":5,\"Username\":\"steve.martin\"}]"
}
_
52
Brian Rogers

この問題が発生しました。ルート名のない配列アイテムが必要な場合は、JArrayを使用してこれを実行できます。

var json = JArray.FromObject(LoadUsers());

Json配列のルート名を「users」にしたい場合は、次を使用できます。

var json = new JObject { ["users"] = JToken.FromObject(LoadUsers()) };
3
polydegmon