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

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);

Related

newtonsoft deserialize group of objects

TL;DR
How do I convert json data that looks like this into a C# object using Newtonsoft.json and JsonConvert.DeserializeObject?
{"start":true,"result":{"label":"Setup Account","item":"name"}}
{"start":false,"result":{"label":"Change Account","item":"address"}}
{"start":false,"result":{"label":"Close Account","item":"account"}}
I am trying to deserialize some json exported from Splunk. The data does not look like an array, but rather a list of json objects between {}. Here are the first three objects of 600+ so you can see the format. The first one is actually the Splunk output. I shortened the "Search" in the next two.
{"preview":false,"result":{"label":"Internal Admin Nav","search":"<view isVisible=\"false\" >\n <label>Internal Admin Nav<\/label>\n <module name=\"Message\" layoutPanel=\"messaging\">\n <param name=\"filter\">*<\/param>\n <param name=\"clearOnJobDispatch\">False<\/param>\n <param name=\"maxSize\">1<\/param>\n <\/module>\n <module name=\"AccountBar\" layoutPanel=\"appHeader\">\n <param name=\"mode\">lite<\/param>\n <\/module>\n <module name=\"LiteBar\" layoutPanel=\"liteHeader\"><\/module>\n<\/view>"}}
{"preview":false,"result":{"label":"Setup Account","search":"AAAA"}}
{"preview":false,"result":{"label":"Contactless Dashboard","search":"BBBB"}}
If I try to create a class by pasting the first three lines into Visual Studio using Paste Special|Paste JSON as Classes, it complains that it is not Json data (Notepad++ seems to think it is though). If I just paste one of them {"preview":false,"result":{"label":"Contactless Dashboard","search":"BBBB"}} I get this object:
public class Rootobject
{
public bool preview { get; set; }
public Result result { get; set; }
}
public class Result
{
public string label { get; set; }
public string search { get; set; }
}
I have tied to deserialize in many ways.
Rootobject jsonObj = JsonConvert.DeserializeObject<Rootobject>(File.ReadAllText(fileName));
Error: Additional text encountered after finished reading JSON content:
List<Rootobject> jsonObj = JsonConvert.DeserializeObject<List<Rootobject>>(File.ReadAllText(fileName));
Error: Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ChecSourcetypes.Program+ObjClass]' 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 'preview', line 1, position 11.'
This is the most promising one and I tried to force it to deserialize by using a JsonObjectAttribute, but that just raised more problems.
I also added this class
public class RootRootobject
{
public List<Rootobject> objects { get; set; }
}
and then used this:
RootRootobject jsonObj = JsonConvert.DeserializeObject<RootRootobject>(File.ReadAllText(fileName));
I have messed with List<> and different objects without any success. I even converted the data to look like this:
[{"preview":false,"result":{"label":"Internal Admin Nav","search":"CCC"}},
{"preview":false,"result":{"label":"Setup Account","search":"AAAA"}},
{"preview":false,"result":{"label":"Contactless Dashboard","search":"BBBB"}}]
How do I read this json into an object? I would not want to change the Splunk output, but I could. I also would like to do it using JsonConvert.DeserializeObject. I recall doing this with Splunk data a few years ago using List<>, but do not remember how.
Thanks.
you have to fix your json to this (actually your last case)
[{"preview":false,"result":{"label":"Internal Admin Nav","search":"CCC"}},
{"preview":false,"result":{"label":"Setup Account","search":"AAAA"}},
{"preview":false,"result":{"label":"Contactless Dashboard","search":"BBBB"}}]
use your first classes
public class Rootobject
{
public bool preview { get; set; }
public Result result { get; set; }
}
and this code
List<RootRootobject> jsonObj = JsonConvert.DeserializeObject<List<RootRootobject>>(yourFixedJson);

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);

Deserialize Json into C# Collection

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;

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

Mass Transit unable to deserialize collections with exactly one element

I've got a Mass Transit message interface like this:
public interface IPerson
{
ICollection<PersonalName> Names { get; }
}
public class PersonalName
{
public string FamilyName { get; set; }
public string GivenName { get; set; }
public string SecondName { get; set; }
public string Use { get; set; }
}
And this works for serializing and deserializing the message using the JsonMessageSerializer. I can also serialize the message using the XmlMessageSerializer, and the result looks a bit like this:
<person>
<names>
<familyName>Simpson</familyName>
<givenName>Homer</givenName>
<secondName>Jay</secondName>
<use>Official</use>
</names>
<names>
<givenName>Homie</givenName>
<use>Nickname</use>
</names>
</person>
And I can deserialize just it if the collection is empty or if it has more than one element. However, if the collection contains exactly one element, when I go to deserialize it, I get this error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.ICollection`1[MyNs.PersonalName]' 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 'person.names.familyName'.
I can fix this by using an array or List<T>, but I'd really like to avoid doing that. Is there a way to get Mass Transit's XmlMessageSerializer to deserialize ICollection<T> types? Since Mass Transit uses Json.NET for serialization under the hood (even for XML), I'm hoping there's some way of annotating the type so that it can accept an ICollection<T>.
Instead of trying to deserialize:
{"FamilyName":"Smith","GivenName":"John"}
you have to pass in an array to deserialize:
[{"FamilyName":"Smith","GivenName":"John"}]

Categories