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
JValue
には、文字列、int、ブール値、日付などの単純な値のみを含めることができます。複雑なオブジェクトを含めることはできません。私はあなたが本当に欲しいのはこれだと思います:
_List<User> list = LoadUsers();
JObject json = new JObject();
json["users"] = JToken.FromObject(list);
_
上記は、User
オブジェクトのリストをユーザーを表すJArray
のJObjects
に変換し、それを新しいusers
のJObject
プロパティに割り当てます。これは、_json["users"]
_のType
プロパティを調べて、Array
であることを確認することで確認できます。
対照的に、この質問に対する別の回答で提案されたようにjson["users"] = new JValue(JsonConvert.SerializeObject(list))
を実行すると(現在は削除されています)、おそらく、探している結果が得られないでしょう。このアプローチでは、ユーザーのリストを文字列にシリアル化し、そこから単純なJValue
を作成してから、JValue
をusers
のJObject
プロパティに割り当てます。 _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\"}]"
}
_
この問題が発生しました。ルート名のない配列アイテムが必要な場合は、JArrayを使用してこれを実行できます。
var json = JArray.FromObject(LoadUsers());
Json配列のルート名を「users」にしたい場合は、次を使用できます。
var json = new JObject { ["users"] = JToken.FromObject(LoadUsers()) };