Deserialize Json into C# Collection - c#

I want to deserialize json into collection of C# objects but getting following error:
{"Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1 because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\r\nPath 'organizations', line 1, position 17."}
Code:
var jSon = "{\"Houses\":[{\"id\":\"123\",\"doorNumber\":22},
{\"id\":\"456\",\"deniNumber\":99}
]}";
var temp = JsonConvert.DeserializeObject<List<House>>(jSon);
}
public class House
{
public int Id { get; set; }
public int DoorNumber { get; set; }
}

The JSON you've shown is an Object with a Property called Houses that contains your array. Note how the outer Json is surrounded by { } and not [ ] which is why you're seeing that error. You'll need to select only the value of that property if you want to deserialize to a list of House. You can do that using JObject and then selecting the Houses property specifically.
var jobj = JObject.Parse(jSon);
var houses = JsonConvert.DeserializeObject<List<House>>(jobj["Houses"].ToString());
Alternatively you could do:
var houses = JObject.Parse(jSon)["Houses"].ToObject<List<House>>();
If you want to be able to map it in one step without using JObject you'd have to have another class that wraps your House list and maps directly to the JSON you've shown.
public class HouseList
{
public List<House> Houses {get; set;}
}
Given this object you'd be able to do
var houses = JsonConvert.DeserializeObject<HouseList>(jSon).Houses;

Related

Json deserialization - System.Collections.Generic.List error [duplicate]

This question already has answers here:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1
(6 answers)
WriteLine with a class
(9 answers)
Closed last year.
I got http result in JSON like that
{
"success":true,
"message":[
],
"conversationList":[
"dd184c5a-7eb7-4e98-b588-975853c51b18",
"a3c25d14-d0d5-4e79-928b-1123fe1ba587",
"8c5e2869-43f8-4555-9afd-3b1e679d5ed0",
"843dcbd4-33fc-487f-9971-7fd80ff378c4",
"62dcee64-aeb6-448d-9422-c6b94a22aa02",
"409a8da6-bf32-4dee-923c-213a9971283c"
]
}
I make classes like that:
public class Root
{
public bool success { get; set; }
public List<object> message { get; set; }
public List<string> conversationList { get; set; }
}
and deserialization like this:
var deserializedJson = JsonConvert.DeserializeObject<List<Root>>(result);
Then I got this error:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ConsoleApp9.Root]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'success', line 1, position 11.'
I want to use foreach on this and get all conversationList. How can I resolve this error?
you don' t have a list in your root. Use this
var deserializedJson = JsonConvert.DeserializeObject<Root>(result);

Serialize and deserialize datetime with newtonsoft

I have a class which contains the ocject DateTime.
public class Refuel
{
public DateTime DateTime { get; set; }
public string Litre { get; set; }
}
When deserializing my text file I get an error.
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[OD_TankApp.Models.Refueling]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'DateTime', line 1, position 12.
I tried already with Json settings but it didnt helped.
JsonSerializerSettings settings = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat};
this is the json string:
"{\"DateTime\":\"2019-02-28T16:21:06.36845+01:00\",\"Litre\":\"23\"}}"
You are trying to deserialize a json string which represents a single object into a list/array of objects which will not work. Either deserialize it into a single object like this:
var obj = JsonConvert.DeserializeObject<Refuel>(json);
Or change your json string to contain a list of objects:
"[{\"DateTime\":\"2019-02-28T16:21:06.36845+01:00\",\"Litre\":\"23\"}]"
Now you can deserialize it like that:
var objArray = JsonConvert.DeserializeObject<Refuel[]>(json);
If you want to deserialize an array, you'll need to secify that ([])
JsonConvert.DeserializeObject<Refuel[]>(json);

Convert an FeedResponse<Class> into List<Class> in DocumentDB

I'm trying to convert a FeedResponse into List but failing to serialize the string as it throws an error
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Lutran.Api.Models.Infinity]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'token', line 1, position 9.
I have used the logic for pagination using the this link and getting the data when returning the entire output object but when im trying to convert it fails.Tried using an ienumerable object but it shows type conversion error.Used a dynamic object but cannot extract ResponseContinuation value from it.
Using Newton Soft to convert the json(deserialize the string)
var query = client.CreateDocumentQuery<Document>(collection, options).AsDocumentQuery();
if (query.HasMoreResults)
{
var result = await query.ExecuteNextAsync<LeadDataView>();
objLeadDataView.ResponseContinuation = result.ResponseContinuation;
objLeadDataView.InfinityDataView = JsonConvert.DeserializeObject<List<Infinity>>(result.ToString());
response = objLeadDataView;
}
I Figured it out
public class LeadDataView
{
public string ResponseContinuation { get; set; }
public FeedResponse<Infinity> InfinityDataView { get; set; }
}
if (query.HasMoreResults)
{
var result = await query.ExecuteNextAsync<Infinity>();
objLeadDataView.ResponseContinuation = result.ResponseContinuation;
objLeadDataView.InfinityDataView = result;
response = objLeadDataView;
}
So the above code sent the continuation token on top and infinity class data below.enter image description here

How to convert JSON Response to a List in C#?

This might be a basic question but I am stuck while converting a JSON Response to a List.
I am getting the JSON Response as,
{"data":[{"ID":"1","Name":"ABC"},{"ID":"2","Name":"DEF"}]}
Have defined a Class,
class Details
{
public List<Company> data { get; set; }
}
class Company
{
public string ID { get; set; }
public string Name { get; set; }
}
Have tried this for converting,
List<Details> obj=List<Details>)JsonConvert.DeserializeObject
(responseString, typeof(List<Details>));
But this returns an error, saying
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Client.Details]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Kindly help!
You don't have a List<Detail> defined in your JSON. Your JSON defines one Detail record, which itself has a list of companies.
Just deserialize using Details as the type, not List<Details> (or, if possible, make the JSON wrap the single detail record into a one item array).
You need to Deserialize like this:
var Jsonobject = JsonConvert.DeserializeObject<Details>(json);
using classes generated by json2csharp.com:
var Jsonobject = JsonConvert.DeserializeObject<RootObject>(json);
and your classes should be :
public class Datum
{
public string ID { get; set; }
public string Name { get; set; }
}
public class RootObject
{
public List<Datum> data { get; set; }
}
you can always use json2csharp.com to generate right classes for the json.
You can use JavaScriptDeserializer class
string json = #"{""data"":[{""ID"":""1"",""Name"":""ABC""},{""ID"":""2"",""Name"":""DEF""}]}";
Details details = new JavaScriptSerializer().Deserialize<Details>(json);
EDIT: yes, there's nothing wrong with OP's approach, and Servy's answer is correct. You should deserialize not as the List of objects but as the type that contains that List

How to convert a Json string to a class that has a list in Json.Net with C# when the json has an array one level deeper

I have a C# Application in which I am using Json.Net from Nuget.
I get a json from my server which I need to convert into a C# object and with a few modifications I will send it back to the server as json.
Here's my model in C# (which I got after converting the server xsd)
public class Tags
{
public List<Tag> tagData { get; set; }
}
public class Tag
{
public string name {get; set;}
}
Here's my JSON string that is obtained from the server and an attempt at conversion to my model
//Json string obtained from server (hardcoded here for simplicity)
string json = "{tagData: {tags : [ { name : \"John\"}, { name : \"Sherlock\"}]}}";
//An attempt at conversion
var output = JsonConvert.DeserializeObject<Tags>(json);
This is the exception I get with the above code
An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[jsonnetExample.Tag]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'tagData.tags', line 1, position 17.
After understanding the above message I tried the following 2 things in the hope of fixing it.
A.I tried putting a JsonProperty to my first model.
[JsonProperty(PropertyName = "tags")]
This didn't throw the exception anymore but the output tagData was null.
B. I modified my model as follows
public class Tags
{
public WrapTag tagData { get; set; }
}
public class WrapTag
{
public List<Tag> tags { get; set; }
}
public class Tag
{
public string name {get; set;}
}
This didn't throw any exception and populated the objects as expected. But Now I lost the one to one mapping between xsd(classes from the server) to my client model classes. Is it possible to get this deserialization working without the creation of the WrapTag class?
I would be very glad if someone can point me in the right direction.
Thanks in advance.
Here's one option, using JObject.Parse:
string json = "{tagData: {tags : [ { name : \"John\"}, { name : \"Sherlock\"}]}}";
List<Tag> tagList = JObject.Parse(json)["tagData"]["tags"].ToObject<List<Tag>>();
// or:
// List<Tag> tagList = JObject.Parse(json).SelectToken("tagData.tags")
// .ToObject<List<Tag>>();
Tags tags = new Tags { tagData = tagList };

Categories