Cannot deserialize the current JSON object (e.g. {"name":"value"}) - c#

Please Help me out i am new in xamarin.forms and C# i have try every solution which is given in stackoverflow but cannot avail to solve
using (var httpClient = new HttpClient())
{
var response = httpClient.GetAsync(Url).Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
string contents = await responseContent.ReadAsStringAsync();
List<abcModel> tm = JsonConvert.DeserializeObject<List<abcModel>>(contents);
abcMaster = new ObservableCollection<SummaryModel>();
var c = tm[0].SSum.Count();
}
}
Model
public class abcModel
{
public List<SSum> SSum { get; set; }
}
public class SSum
{
public string Name{ get; set; }
}
My Json
{"a":[{"SSum":[{"Name":"Earth"}]}]}
Error:-
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[abcModel]' 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.

Because you obviously just want to deserialize a nested part of your json, do it like this:
var result = JsonConvert.DeserializeObject<Dictionary<string, List<abcModel>>>(json);

You're missing the a property in your JSON. You can deserialize into a class that has that property:
public class MyType
{
public List<abcModel> A { get; set; }
}
JsonConvert.DeserializeObject<MyType>(json);
Or skip that property all together (#stefankmitph's answer works well), here's another alternative:
JObject obj = JObject.Parse(json);
List<abcModel> model = obj["a"].ToObject<List<abcModel>>();
Just a note: normally C# classes are PascalCased.

If you already have the JSON string you should use a generator like json2csharp to create the response DTO. This will prevent mistakes in what is a collection versus single object.
public class SSum
{
public string Name { get; set; }
}
public class A
{
public List<SSum> SSum { get; set; }
}
public class RootObject
{
public List<A> A { get; set; }
}
Now you can deserialize the complete object:
tm = JsonConvert.DeserializeObject<RootObject>(contents);

Related

Deserializing JSON with Newtonsoft, using a specific class

I know there are lots of questions on how to do this...
I have a pretty complex JSON returned from an API and I am trying to work my way through it. I simplified the JSON answer so it holds one of the immanent problems.
The simplified JSON answer
{"data":[{"type":"task","id":"10118"},{"type":"task","id":"10004"}]}
My class to be used for the deserialisation
namespace TestJsonDeserializeApp
{
class jsonTask
{
public List<Data> data { get; set; }
public class Data
{
public string id { get; set; }
public string type { get; set; }
}
}
}
How I want to do the deserialisation
List<jsonTask> test = JsonConvert.DeserializeObject<List<jsonTask>>(strJSON);
and finally the error message I am getting
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[TestJsonDeserializeApp.jsonTask]' 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 'data', line 1, position 8.
Can one of you tell me how I have to write the jsonTask class to fit the structure of the JSON input?
Copy your JSON. Open Visual studio. Create new C# class file. Now Select below menu option:
Edit > Paste Special > Paste JSON as classes
This will create a class as below
public class Rootobject
{
public Datum[] data { get; set; }
}
public class Datum
{
public string type { get; set; }
public string id { get; set; }
}
Now change RootObject to jsonTask and deserialise as below
jsonTask test = JsonConvert.DeserializeObject<jsonTask>(strJSON);
With your code you are casting the strJSON to List with a list. You need to remove the outer list since jsonTask alreadyhas the public List data { get; set; }
Try:
jsonTask test = JsonConvert.DeserializeObject(strJSON);

How to Deserialize Json Object - C#

A web service returns JSON object as blew:
JsonString = "{"d":"[{\"sname\":\"S1\",\"region\":\"R1\",\"name\":\"Q1\"},{\"sname\":\"S2\",\"region\":\"R2\",\"name\":\"Q2\"}]"}"
I tried to Deserialize by doing this:
Define the objects
public class RootResponseClass
{
public ResponseParametersClass[] d { get; set; }
}
public class ResponseParametersClass
{
public string sname { get; set; }
public string region { get; set; }
public string name { get; set; }
}
Write the Deserialize Method
JavaScriptSerializer ser2 = new JavaScriptSerializer();
RootResponseClass obj = new RootResponseClass();
obj = ser2.Deserialize<RootResponseClass>(JsonString);
But It is gives error "Cannot convert object of type 'System.String' to type 'NAS.Helpers.ResponseParametersClass[]", So how can i do it!
Solution
public class RootResponseClass
{
public string d { get; set; }
}
And for deserialize method :
JavaScriptSerializer ser2 = new JavaScriptSerializer();
RootResponseClass obj = new RootResponseClass();
obj = ser2.Deserialize<RootResponseClass>(JsonString);
List<ResponseParametersClass> obj2 = new List<ResponseParametersClass>();
obj2 = ser2.Deserialize<List<ResponseParametersClass>>(obj.d.ToString());
You can use the package using Newtonsoft.Json; for deserializing JSON
example
JsonString = "{"d":"[{\"sname\":\"S1\",\"region\":\"R1\",\"name\":\"Q1\"},{\"sname\":\"S2\",\"region\":\"R2\",\"name\":\"Q2\"}]"}";
var foo = JsonConvert.DeserializeObject<RootResponseClass>(JsonString);
foo is your deserialized object.
EDIT
As extra information why the initial way is not working is because your array is starting with quotes so its recognized as a string. After the "{"d": should be just [] instead of "[]"
Thanx Dnomyar96 for pointing that extra out.
Your Json string seems to contain another Json string. So in order to deserialize this, you'd need to deserialize as you're doing now, but change the ResponseParametersClass to string.
Then you'd need to deserialize the string you just got (as a List<ResponseParametersClass>). So in this case you'd need to deserialize in two seperate steps.

How to deserialize JSON to complex object in C#

I'm trying to deserialize json result to wanted object. The result I'm getting is:
{
"base": "EUR",
"date": "2017-06-30",
"rates": {
"AUD": 1.4851,
"BGN": 1.9558,
"BRL": 3.76,
"CAD": 1.4785
}
}
I want this result to deserialize to my object:
public class ExchangeRates
{
public string Base { get; set; }
public DateTime Date { get; set; }
public IList<Rates> Rates { get; set; }
}
public class Rates
{
public string Name { get; set; }
public decimal Value { get; set; }
}
my deserialization looks like this:
using (var httpClient = new HttpClient())
{
var response = httpClient.GetAsync("http://api.fixer.io/latest").Result;
var result = response.Content.ReadAsStringAsync().Result;
var values = JsonConvert.DeserializeObject<ExchangeRates>(result);
}
When I run the program I get following exception:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ConsoleApp4.Rates]' 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 'rates.AUD', line 1, position 49.'
How can I deserialize JSON to my wanted object??
UPDATE 1
Or maybe I can just deserialize 'rates' list?
Take a look at your JSON, specifically rates:
"rates": {
"AUD": 1.4851,
"BGN": 1.9558,
"BRL": 3.76,
"CAD": 1.4785
}
This is very clearly a JSON object, as it has key-value pairs. However, looking at your code, you have defined the corresponding property (Rates) as an IList:
public IList<Rates> Rates { get; set; }
I understand your reasoning behind defining the Rates class. You think that by defining that class, NewtonSoft will deserialize rates the way you want it to. However, this is impossible because rates is not an array, and therefore deserializing it into any kind of IList is impossible.
The easiest and most clear cut solution is to use a dictionary:
public Dictionary<string, decimal> Rates { get; set; }
However, if you don't want to use a dictionary, you need to modify your JSON like so and your solution will work:
"rates":[
{
"Name":"AUD",
"Value":1.4851
},
{
"Name":"BGN",
"Value":1.9558
},
{
"Name":"BRL",
"Value":3.76
},
{
"Name":"CAD",
"Value":1.4785
}
]
By converting rates to an array, and making its contents objects instead of key-value pairs, NewtonSoft can deserialize rates as a list, and its contents as instances of the Rates class.
I agree with the other guys comments: you should use a Dictionary. To achieve the conversion to your final object structure you can use for example an intermediary class with an explicit cast operator.
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Program
{
public void Main()
{
var result = #"{
""base"": ""EUR"",
""date"": ""2017-06-30"",
""rates"": {
""AUD"": 1.4851,
""BGN"": 1.9558,
""BRL"": 3.76,
""CAD"": 1.4785
}}";
var values = (ExchangeRates) JsonConvert.DeserializeObject<TempExchangeRates>(result);
Console.WriteLine(values.Base);
Console.WriteLine(values.Date);
foreach(var rate in values.Rates)
Console.WriteLine(rate.Name + ": " + rate.
}
}
public class TempExchangeRates
{
public string Base { get; set; }
public DateTime Date { get; set; }
public Dictionary<string,decimal> Rates { get; set; }
public static explicit operator ExchangeRates(TempExchangeRates tmpRates)
{
var xRate = new ExchangeRates();
xRate.Base = tmpRates.Base;
xRate.Date = tmpRates.Date;
xRate.Rates = new List<Rates>();
foreach(var de in tmpRates.Rates)
xRate.Rates.Add(new Rates{Name = de.Key, Value = de.Value});
return xRate;
}
}
public class ExchangeRates
{
public string Base { get; set; }
public DateTime Date { get; set; }
public IList<Rates> Rates { get; set; }
}
public class Rates
{
public string Name { get; set; }
public decimal Value { get; set; }
}

Deserializing multiple Json objects from URL to List<T> in c#

I am trying to deserialize multiple Json objects from an API call like this: http://jservice.io/api/clues?category=2537&value=400
But when I run my code, I never get past the Json conversion and nothing is returned to the client when calling the GetQuestions() method.
I wanted to save the id, question, answer and value in a custom c# object so I made this class:
public class JsonQuestion
{
private DataContainer container;
public int id { get; set; }
public string answer { get; set; }
public string question { get; set; }
public int value { get; set; }
public JsonQuestion(string categoryId, int value)
{
using (var webClient = new System.Net.WebClient())
{
var json = webClient.DownloadString("http://jservice.io/api/clues?category=" + categoryId + "&value=" + value);
container = JsonConvert.DeserializeObject<DataContainer>(json);
}
}
public DataContainer GetQuestions()
{
return container;
}
}
Here I am receiving the categoryID and value to the constructor and then creating the URL based on those values to be deserialized. Ideally I want to return the container holding all the questions to a client.
I made a class that holds all the questions received:
public class DataContainer
{
public List<JsonQuestion> Questions { get; set; }
}
Which I use with the DeserializeObject call.
First of all you have wrong idea of how json will deserialize arrays. If you would look at exceptions that is throwing in your code you would get your first mistake:
Additional information: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Application.Program+DataContainer' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
What you are trying to do is deserialize array into object, witch is not possible. So you would need structure of json like this: {"Questions":[content of your json]}. To avoid this you have to change your deserialization to:
JsonConvert.DeserializeObject<List<JsonQuestion>>(json);
Second, JsonConvert will take simplest constructor provided, and will try to use it to create nested sturctures, witch you have multiple. So every time constructor has to be called, JsonConvert will use public JsonQuestion(string categoryId, int value) with fallowing values of null, and 400 (those value are taken form nested item, witch has parameter value set to 400 and no parameter categoryId). So you will fall into recuring loop, becase every time new json document will be downloaded. What you have to do is provide public default constructor of JsonQuestion.
Whole code would look like this:
public class JsonQuestion
{
private List<JsonQuestion> container;
public int id { get; set; }
public string answer { get; set; }
public string question { get; set; }
public int value { get; set; }
public JsonQuestion()
{
}
public JsonQuestion(string categoryId, int value)
{
using (var webClient = new System.Net.WebClient())
{
var json = webClient.DownloadString("http://jservice.io/api/clues?category=" + categoryId + "&value=" + value);
var container = JsonConvert.DeserializeObject<List<JsonQuestion>>(json);
}
}
public DataContainer GetQuestions()
{
return new DataContainer
{
Questions = container,
};
}
}
public class DataContainer
{
public List<JsonQuestion> Questions { get; set; }
}

Converting JSON to List

I am stuck in a step that I am sure should work. I have a method (in a separate class) that should return a List as its value after processing the JSON. I am going to paste the code skipping the JSON configuration stuff:
public static dynamic CustInformation(string Identifier)
{
//SKIPPED JSON CONFIG STUFF (IT'S WORKING CORRECTLY)
var result = "";
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
dynamic d;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
return JsonConvert.DeserializeObject<List<Models.RootObject>>(result);
}
The model was generated using C# to Json converter:
public class Record
{
public string idIdentifier { get; set; }
public string KnowName1 { get; set; }
public string KnowAddress1 { get; set; }
public string KnowRelation1 { get; set; }
public string KnowPhone1 { get; set; }
public string KnowName2 { get; set; }
public string KnowAddress2 { get; set; }
//.....skipped other variables
}
public class RootObject
{
public List<Record> record { get; set; }
}
And I am calling the method like this:
var model = Classes.EndPoint.CustInformation(identifier);
Yet I am getting this error everytime:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Models.RootObject]' 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 'record', line 1, position 10.
EDIT: JSON
{
"record": [
{
Identifier": "DQRJO1Q0IQRS",
"KnowName1": "",
"KnowAddress1": "",
"KnowRelation1": "",
"KnowPhone1": "",
"KnowName2": "",
"KnowAddress2": "",
//.....MORE STYFF
}
]
}
Like I said in the comments, and like the error message clearly states, you're trying to deserialize into a list of root objects, but your JSON is only one root object, not an array.
Here's what your C# should be.
return JsonConvert.DeserializeObject<Models.RootObject>(result);

Categories