List list = LoadUsers();
JObject json = new JObject();
json[\"users\"] = new JValue(list);
Doesn\'t seem to be working?
Error
A JValue
can only contain simple values like strings, ints, booleans, dates and the like. It cannot contain a complex object. I suspect what you really want is this:
List<User> list = LoadUsers();
JObject json = new JObject();
json["users"] = JToken.FromObject(list);
The above will convert the list of User
objects into a JArray
of JObjects
representing the users, then assign that to the users
property on the new JObject
. You can confirm this by examining the Type
property of json["users"]
and see that it is Array
.
In contrast, if you do json["users"] = new JValue(JsonConvert.SerializeObject(list))
as was suggested in another answer to this question (now deleted), you will probably not get the result you are looking for. That approach will serialize the list of users to a string, create a simple JValue
from that, and then assign the JValue
to the users
property on the JObject
. If you examine the Type
property of json["users"]
, you will see that it is String
. What this means is, if you later try to convert the JObject
to JSON by using json.ToString()
, you will get double-serialized output instead of the JSON you probably expect.
Here is a short demo to illustrate the difference:
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; }
}
}
Output:
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\"}]"
}
I had this issue, you can now use JArray to get this done, if you just want the array items with no root name.
var json = JArray.FromObject(LoadUsers());
If you want the root name of the json array to be "users", you can use
var json = new JObject { ["users"] = JToken.FromObject(LoadUsers()) };