Can Json.Net handle a List<object>?

asp.net, c#, json, json.net

Solution

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\"}]"
}

Problem

``` List<User> list = LoadUsers(); JObject json = new JObject(); json["users"] = new JValue(list); ``` Doesn't seem to be working? Error: ``` Could not determine JSON object type for type System.Collections.Generic.List`1 ```

Original source