Deserializing json values into a list - c#

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"];

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.

C# Json.Net - How to deserialize complex object Google Elevation

I have this JSON:
{
"results" : [
{
"elevation" : 25.51896667480469,
"location" : {
"lat" : -26.90408425509977,
"lng" : -49.04650926589966
},
"resolution" : 152.7032318115234
}
],
"status" : "OK"
}
This class:
public class RootObject
{
public Elevacao[] results { get; set; }
public string status { get; set; }
}
public class Elevacao
{
public Decimal elevation { get; set; }
public Decimal resolution { get; set; }
public dados[] location { get; set; }
}
public class dados
{
public Decimal lat { get; set; }
public Decimal lng { get; set; }
}
This code:
public ActionResult Teste()
{
var url = "http://maps.googleapis.com/maps/api/elevation/json?locations=-26.904084255099768,-49.04650926589966&sensor=false&format=json";
var json = new WebClient().DownloadString(url);
RootObject m = JsonConvert.DeserializeObject<RootObject>(json);
return View();
}
And this error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'TCC.Controllers.dados[]' 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 'results[0].location.lat', line 6, position 20.
where I went wrong?
In the JSON, location is an object, not an array. However, in your Elevacao class location is defined as an array. They need to match in order for deserialization to work correctly. That is what the error message is trying to tell you.
To fix it, change this line:
public dados[] location { get; set; }
To this:
public dados location { get; set; }
location in your JSON is a single object, not an array.
You want "results" from the JSONObject. Use json.results

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.

Json.net deserialize error

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

Categories