Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Json.Net handle a List<object>?

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 
like image 255
mrblah Avatar asked Jul 30 '09 17:07

mrblah


People also ask

Can JSON serialize a list?

Json.NET has excellent support for serializing and deserializing collections of objects. To serialize a collection - a generic list, array, dictionary, or your own custom collection - simply call the serializer with the object you want to get JSON for.

What is Jsonconvert SerializeObject C#?

SerializeObject Method (Object, Type, JsonSerializerSettings) Serializes the specified object to a JSON string using a type, formatting and JsonSerializerSettings. Namespace: Newtonsoft.Json.

What is JObject parse in C#?

JObject class has parse method; it parses the JSON string and converts it into a Key-value dictionary object. In the following example, I have used “JObject. Parse” method and retrieved data using key. string jsonData = @"{ 'FirstName':'Jignesh', 'LastName':'Trivedi' }"; var details = JObject.


2 Answers

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\"}]" } 
like image 115
Brian Rogers Avatar answered Sep 21 '22 21:09

Brian Rogers


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()) }; 
like image 30
polydegmon Avatar answered Sep 21 '22 21:09

polydegmon