Json.net deserialize error - c#

I'm parsing a JSON string into an ObservableCollection, but when I do it Json.net throws this error:
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'MVPTracker.ViewModels.DataModels+League+Position' 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.
My DataModel, ViewModel and Loading are below:
DataModel:
public class League
{
public string name { get; set; }
public string code { get; set; }
public string imageUrl { get; set; }
public Position positions = new Position();
public class Position
{
public string name { get; set; }
public string code { get; set; }
public string imageUrl { get; set; }
public string[] statistics { get; set; }
}
}
Loading/ViewModel:
private ObservableCollection<DataModels.League> _leagues = new ObservableCollection<DataModels.League>();
public ObservableCollection<DataModels.League> Leagues
{
get { return _leagues; }
set { _leagues = value; NotifyPropertyChanged("Leagues"); }
}
public async void Load()
{
string leaguesJSON = await ServerConnector.LoadOrganizations();
Leagues.Clear();
Leagues = JsonConvert.DeserializeObject<ObservableCollection<DataModels.League>>(leaguesJSON);
}
I've tried setting the ObservableCollection's to IList/ICollection's to no avail.
edit: Here is the json that I am parsing: http://pastebin.com/QVnikitV

Your positions field in the C# code represents a single object of type Position. Your JSON object's positions field represents an array.
So your C# code would need to be changed to an array to match:
public Position[] positions { get; set; }

Related

Multiple employees Json gives Deserializing error

I am reading 2 REST APIs using Httpclient in C#. The APIs return following employee data in JSON format:
1st API
{
"status": "OK",
"content": {
"empid1": 89900,
"empid2": 45550,
"empid3": 22350}
}
2nd API
{
"status": "OK",
"content": {
"empid1": "grade1",
"empid1": "grade2",
"empid1": "grade2"}}
Classes defined and code used is as follows:
public class content
{
public string empid { get; set; } // e.g. empid3
public double salary { get; set; } // e.g. 89900
public string grade { get; set; } // e.g. Grade1
}
public sealed class WrapperEmployees
{
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("data")]
public List<content> empdata { get; set; } = new List<data>();
}
To deserialize, used this-
WrapperEmployees nj = JsonConvert.DeserializeObject<WrapperEmployees>(response);
But, last line gives error on deserialization:
Cannot deserialize current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[CsharpSample.App_Code.Employee]' 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 'content.emp1', line 4, position 18.
Is my class structure incorrect?
My ultimate aim is to fetch common data from both APIs against employees.
Option 1: use specific classes for each json deserialization:
class EmployeesSalaries {
public string Status { get; set; }
public Dictionary<string, int> content { get; set; };
}
class EmployeesGrades {
public string Status { get; set; }
public Dictionary<string, string> content { get; set; };
}
Option 2: deserialize to common class, but you will get 'good' content values only if they are int/string. If they will be objects - you will have JObjects as values.
class EmployeesData {
public string Status { get; set; }
public Dictionary<string, object> content { get; set; };
}

How to fix 'Cannot deserialize the current JSON array into type 'passages' because requires a JSON object (e.g. {"name":"value"}) to deserialize

I am trying to read and access a large JSON file from local directory using newtonsoft.json in c# but always gave me the error. I created two classes for accessing it.
This is my example JSON data:
{
"passages": [
{
"passage_text": "xxxxxxx",
"url": "xxxxx",
}
]
"answer":"xxxxxx",
"query_id":"Xxxxx"
}
here is the code I have tried:
public class collection
{
public passages passages { get; set; }
public String answers { get; set; }
public String query_id { get; set; }
}
public class passages
{
public String url { get; set; }
public String passage_text { get; set; }
}
Here is the part I tried to read and access to JSON file:
String jsonPath = #"C:\Users\admin\Desktop\647\project\collection\sample_collection.json" ;
var serializer = new JsonSerializer();
StreamReader sr = new StreamReader(jsonPath);
JsonTextReader reader = new JsonTextReader(sr);
reader.SupportMultipleContent = true;
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
collection c = serializer.Deserialize<collection>(reader);
Console.WriteLine(c.passages.url);
}
}
And it gave me this error:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'LuceneIndexApplication.passages' 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.
Path '[0].passages', line 1, position 15.'
you are trying to map passages to from an array into a list.
so all that you should need to change is:
public class collection
{
public passages passages { get; set; }
public String answers { get; set; }
public String query_id { get; set; }
}
should be
public class collection
{
public List<passages> passages { get; set; }
public String answers { get; set; }
public String query_id { get; set; }
}
note the List in the latter.

Deserializing json values into a list

Well I've been through multiple questions now about the same thing, still cant understand how the Newtonsoft works completely.
The response from the web page is,
{"status":[{"domain":"test.com","zone":"com","status":"active","summary":"active"}]}
I have the class made for parsing,
public class Status
{
public string name { get; set; }
public string zone { get; set; }
public string status { get; set; }
public string summary { get; set; }
}
And the DeserializeObject
IList<Status> domains = new List<Status>();
domains = JsonConvert.DeserializeObject<List<Status>>(src);
but it still doesn't want to execute the DeserializeObject, it keeps returning the error,
An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Domain_Checker.Status]' 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.
Any ideas please?
According to your json, you need a root object
public class Root
{
public List<Status> Status {get;set;}
}
var root = JsonConvert.DeserializeObject<Root>(src);
For deseralizing the JSON you need the class structure like this
public class Status
{
[JsonProperty("domain")]
public string name { get; set; }
[JsonProperty("zone")]
public string zone { get; set; }
[JsonProperty("status")]
public string status { get; set; }
[JsonProperty("summary")]
public string summary { get; set; }
}
public class ClsStatus
{
[JsonProperty("status")]
public List<Status> status { get; set; }
}
Now if you closely have a look at [JsonProperty("domain")] public string name { get; set; } I have used the name instead of domain. but still the deseralization will be done because of JsonProperty.
Just Deserialize it comfortably like.
string jsonstr = File.ReadAllText("YourJSONFile");
ClsStatus csObj = JsonConvert.DeserializeObject<ClsStatus>(JsonStr);
There is already answer how to parse this json to your own object. If you don't need that you can convert json to JObject. From JObject you can retrieve any value you want like this:
var json = {"status":[{"domain":"test.com","zone":"com","status":"active","summary":"active"}]};
var jsonObject = JObject.Parse(json);
var jsonProperty = jsonObject["status"][0]["domain"];

Can't implement Iterator design pattern after JsonConvert when trying to Deserialize json

I have the following Object that matches the pattern of a JSON object i get from one REST request I send:
public class MyObject
{
public List<string> columns { get; set; }
public List<List<string>> rows { get; set; }
public DisplayValue displayValue { get; set; }
public string currency { get; set; }
public object alert { get; set; }
}
public class DisplayValue
{
public Id DisplayId { get; set; }
}
public class Id
{
public List<string> IdToName { get; set; }
}
this object match to the response I get and the next code is working with the upper implementation of MyObject (I'm using C#'s RestSharp):
var response = client.Execute(request);
result = JsonConvert.DeserializeObject<MyObject>(response.Content);
Now I would like to implement the Iterator design pattern on MyObject since MyObject.rows is the only field I actually use.
So I've changed MyObject class to the following
public class MyObject : IEnumerable<List<string>
{
public List<string> columns { get; set; }
public List<List<string>> rows { get; set; }
public DisplayValue displayValue { get; set; }
public string currency { get; set; }
public object alert { get; set; }
}
public IEnumerator<List<string>> GetEnumerator()
{
foreach (List<string> row in rows)
{
yield return row;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class DisplayValue
{
public Id DisplayId { get; set; }
}
public class Id
{
public List<string> IdToName { get; set; }
}
But when I try to JSONConvert I get the following exception:
Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type
'MyObject' 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.
Any idea to why is this happening?
The problem is that Json.NET will try to serialize any POCO that implements IEnumerable<T> for some T as a JSON array rather than a JSON object, as is documented here. Since your JSON is presumably not an array, you receive the exception you are seeing.
Since you don't want your MyObject serialized as an array, you can force Json.NET to (de)serialize it as an object instead by marking it with [JsonObject]:
[JsonObject]
public class MyObject : IEnumerable<List<string>>
{
public List<string> columns { get; set; }
public List<List<string>> rows { get; set; }
public DisplayValue displayValue { get; set; }
public string currency { get; set; }
public object alert { get; set; }
// Implementation of IEnumerable<List<string>>...
}
See JsonObjectAttribute force object serialization.

Parsing an Array of Json into a C# Class

Here is my code:
Encoding enc = System.Text.Encoding.GetEncoding(1252);
StreamReader loResponseStream = new StreamReader(resp.GetResponseStream(), enc);
JsonSerializer serializer = new JsonSerializer();
JsonTextReader jsreader = new JsonTextReader(loResponseStream);
results = (mHealthData)serializer.Deserialize(jsreader, typeof(mHealthData)); ***
loResponseStream.Close();
public class mHealthData
{ // Class for the Mhealth Data
public class RootObject
{
public string source { get; set; }
public string name { get; set; }
public string type { get; set; }
public string unit { get; set; }
public double value { get; set; }
public string timestamp { get; set; }
}
}
This is the error I receive On the line marked with a **:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'MHealthPlugin.mHealthData' 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<T> 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.
I have no clue how to fix this. I've tried putting List<mHealthData> practically everywhere in the code and it doesn't help. The other rest Calls I do work fine.
For reference, here is an example of what the JSON I'm trying to parse looks like:
[{"source":"hi","name":"G","type":"number","unit":null,"value":126,"timestamp":"1974-07-27T09:35:12Z"},{"source":"hi","name":"G","type":"number","unit":null,"value":120,"timestamp":"1974-07-27T09:35:12Z"}]
Your mHealthData class doesn't have anything in it, except a nested class. Take a step back and see how your data is supposed to be defined.
It looks like you want a RootObject class. In that case, the class should be:
public class RootObject
{
public string source { get; set; }
public string name { get; set; }
public string type { get; set; }
public string unit { get; set; }
public double value { get; set; }
public string timestamp { get; set; }
}
Then when you deserialize, you'll end up with an object of type RootObject[] - your JSON is simply an array, not an object containing an array.

Categories