I have a big problem parsing JSON in C# in Windows Phone 8 app.
The application close when I try to execute this part of the code. The problem append when the C# code deserialize json.
See below the code : C# (deserialization + class forms) and JSON result.
Thanks for your answers.
public partial class MyGrades : PhoneApplicationPage
{
string token = string.Empty;
string mail = string.Empty;
public class MyGradesJson
{
[JsonProperty("periods")]
public Periods periods { get; set; }
}
public class Periods
{
[JsonProperty("period")]
public List<Perioddata> perioddata { get; set; }
}
public class Perioddata
{
[JsonProperty("period")]
public Period period { get; set; }
// [JsonProperty("name")]
// public List disciplines { get; set; }
}
public class Period
{
[JsonProperty("id")]
public int id { get; set; }
[JsonProperty("name")]
public string name { get; set; }
[JsonProperty("start_date")]
public string start_date { get; set; }
[JsonProperty("end_date")]
public string end_date { get; set; }
}
HttpResponseMessage response = await httpClient.SendAsync(requestMessage);
string responseAsString = await response.Content.ReadAsStringAsync();
var resJson = JsonConvert.DeserializeObject<Periods>(responseAsString);
}
Here is the Json answer :
{
"periods":[
{
"period":{
"id":1,
"name":"Year 1",
"start_date":"2000-01-01",
"end_date":"2001-06-30"
},
"disciplines":[
{
"discipline":{
"id":6,
"name":"Potions"
},
"grades":[
{
"id":11,
"note":2,
"coefficient":2,
"assessment":"yolo",
"teacher":{
"id":2,
"user_id":4,
"login":"snape_se",
"name":"Snape, Severus"
}
},
{
"id":15,
"note":10,
"coefficient":1,
"assessment":"test",
"teacher":{
"id":2,
"user_id":4,
"login":"snape_se",
"name":"Snape, Severus"
}
}
]
}
]
}
]
}
I think your app is broken because your have null in your resJson.
The JSON you provided will not be deserialized into Perods object instance.
Try to generate C# classes from JSON. If this feature is not avaliable in your version of VS, try to use online tools. For example http://json2csharp.com/
Related
I apologize in advance for the poor explanation of my problem.
I'm trying to read a JSON array that contains data.
Here's how the JSON looks:
{
"playerstats": {
"steamID": "76561198071680006",
"gameName": "GameName",
"achievements": [
{
"apiname": "AchievementName1",
"achieved": 0, <--- Data that I want to read
"unlocktime": 0
},
{
"apiname": "AchievementName2",
"achieved": 0, <--- Data that I want to read
"unlocktime": 0
},
{
"apiname": "AchievementName2",
"achieved": 1, <--- Data that I want to read
"unlocktime": 1477847680
}
]
,
"success": true
}
}
I'm trying to look at Newtonsoft.Json and how to use that yet I'm at a complete loss as to how to use this. Any help would be appreciated.
You can try JsonConvert.DeserializeObject to read json data.
Having
public class Rootobject
{
public Playerstats playerstats { get; set; }
}
public class Playerstats
{
public string steamID { get; set; }
public string gameName { get; set; }
public Achievement[] achievements { get; set; }
public bool success { get; set; }
}
public class Achievement
{
public string apiname { get; set; }
public int achieved { get; set; }
public int unlocktime { get; set; }
}
You can try this:
var filePath = path to your file;
var jsonData = System.IO.File.ReadAllText(filePath);
Rootobject objectValue =
Newtonsoft.Json.JsonConvert.DeserializeObject<Rootobject>(jsonData);
Note: you should remove <--- Data that I want to read parts from your json data because currently it is not a valid json format.
You may access to your desired properties like this
objectValue.playerstats.achievements[0].achieved //0
objectValue.playerstats.achievements[1].achieved //0
objectValue.playerstats.achievements[2].achieved //1
I am trying to de-serialize a weird complex json string but having issues. I am getting an exception:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Response' because the type requires a JSON object (e.g. {"name":"value"})
The Json looks like this
{
"success":true,
"error":null,
"response":{
"responses":[
{
"success":true,
"error":null,
"response":{
"ob":{
"icon":"sunny.png",
"weatherShort":"Sunny"
}
},
"request":"requeststring"
},
{
"success":true,
"error":null,
"response":[
{
"indice":{
"current":{
"dateTimeISO":"2016-08-09T10:00:00-05:00",
"indexENG":"dry"
}
}
}
],
"request":"requeststring"
}
]
}
}
The problem when trying to create a C# class is that inside the responses list there is a Response object and a Response list.
Here is my class structure:
public class Responses
{
public bool success { get; set; }
public object error { get; set; }
public Response response { get; set; }
public List<Response> responses { get; set; }
public string request { get; set; }
}
public class Indice
{
public Current current { get; set; }
}
public class Current
{
public string indexENG { get; set; }
public string dateTimeISO { get; set; }
}
public class Ob
{
public string icon { get; set; }
public string weatherShort { get; set; }
}
public class Response
{
public List<Responses> responses { get; set; }
public Indice indice { get; set; }
public Ob ob { get; set; }
}
public class RootJsonObject
{
public bool success { get; set; }
public object error { get; set; }
public Response response { get; set; }
}
Am I doing something completely wrong here to handle the Responses list with a Response object and a Response list?
In case anyone wants to know, here is how I deserialize it:
RootJsonObject obj = JsonConvert.DeserializeObject<RootJsonObject>(response);
response being the string from a web request.
I am just trying to figure out how to map this strange JSON to a C# class. I've tried quite a few different class structures but seem to get the same exception regardless. I've also tried c# class generators but they don't give a decent output for this particular JSON. Appreciate any input! Thanks!
There is an error in your JSON. Second element in array has square brackets wrapping classic curly brackets, as if response was a collection but it's not. It's expected to be of type Response:
{
"success": true,
"error": null,
"response": [ <<<HERE {
"indice": {
"current": {
"dateTimeISO": "2016-08-09T10:00:00-05:00",
"indexENG": "dry"
}
}
}] <<<HERE,
"request": "requeststring"
}
Final, proper JSON that you should have received would look like this:
{
'success': true,
'error': null,
'response': {
'responses': [{
'success': true,
'error': null,
'response': {
'ob': {
'icon': 'sunny.png',
'weatherShort': 'Sunny'
}
},
'request': 'requeststring'
}, {
'success': true,
'error': null,
'response': {
'indice': {
'current': {
'dateTimeISO': '2016-08-09T10:00:00-05:00',
'indexENG': 'dry'
}
}
},
'request': 'requeststring'
}]
}
}
I have a Json of type :
{
"JobProcessors": [
{
"JobName": "ArchivalJob",
"IsEnabled": true,
"Batching": {
"BatchSize": 0,
"DegreeOfParallelism": -1
},
"Settings": {
"ArchivalJobCollectionPageSize": 50
}
},
{
"JobName": "AuditLogJob",
"IsEnabled": false,
"Batching": {
"BatchSize": 10,
"DegreeOfParallelism": -1
},
"Settings": {}
}
],
"ScheduledJobs": [
{
"JobName": "RemoteStartClientCommandJob",
"PrimaryAction": {
"ConnectionString": "#JobProcessorsIntegrationSBConnectionStringValue#",
"Settings": {
"LeadTimeInSeconds": "600",
"MaxSrsJobCount": 25
}
},
"ErrorAction": {
"ConnectionString": "#PairedJobProcessorIntegrationSBConnectionStringValue#",
"EntityPath": "remotestartqueue",
"Settings": {
"LeadTimeInSeconds": "600",
"MaxSrsJobCount": 25
}
}
}
]
}
I want to check the "IsEnabled" property for all "JobName" for which come under "JobProcessors" category.
In C# what i Have used till now is :
dynamic parsedJson = JsonConvert.DeserializeObject(reader.GetString(1));
foreach (var item in parsedJson)
{
foreach (var smallitem in item)
{
foreach (var tag in smallitem)
{
if(tag.IsEnabled.toString()=="true"){
Console.WriteLine("true");
}
}
}
}
This is giving me correct result except the fact that it also iterates for "ScheduledJobs" . But the main issue is :
Is this the right or most efficient way to do this ? If possible suggest some better method .
One that i know of is using classes , but i may not know the json structure beforehand. Also the json is very huge so making classes can be cumbersome !!
Given that you are already doing JObject.Parse(jsonstring); to parse your JSON string, you can use SelectTokens() with a JSONPath query to find all "JobName" objects under "JobProcessors":
// I want to check the "IsEnabled" property for all "JobName" for which come under "JobProcessors"
foreach (var job in root.SelectTokens("..JobProcessors[?(#.JobName)]"))
{
var isEnabled = (bool?)job["IsEnabled"];
Debug.WriteLine(string.Format("Job {0}: IsEnabled={1}", job["JobName"], isEnabled));
}
Notes:
.. is the recursive descent operator: it recursively descends the JToken hierarchy returning each item, subsequently to be matched against the remaining parts of the query string.
JobProcessors returns values of properties of that name.
[?(#.JobName)] returns array items (of JobProcessors in this case) that are objects with a JobName property.
(bool?) casts the value of "IsEnabled" to a boolean or null if missing.
And the output of this is:
Job ArchivalJob: IsEnabled=True
Job AuditLogJob: IsEnabled=False
As in your code snippet we are using two foreach it may take time for large object. So we can do the same thing in a single foreach or if you have some specific node to fetch or search we can use linq, and for this first we need to convert our json object into c# object. For converting Json object to C# you can use this site "http://json2csharp.com/" then we can Deserialize Json object into c#.
It will be something like this
string jsonString = "your Json Object as string";
var jsonObject = JsonConvert.DeserializeObject<RootObject>(jsonString);
foreach (JobProcessor obj in jsonObject.JobProcessors)
{
string JobName = obj.JobName;
bool value=obj.IsEnabled;
}
And I also converted given Json in c# object if the Json object is same you can directly use these classes.
public class Batching
{
public int BatchSize { get; set; }
public int DegreeOfParallelism { get; set; }
}
public class Settings
{
public int ArchivalJobCollectionPageSize { get; set; }
}
public class JobProcessor
{
public string JobName { get; set; }
public bool IsEnabled { get; set; }
public Batching Batching { get; set; }
public Settings Settings { get; set; }
}
public class Settings2
{
public string LeadTimeInSeconds { get; set; }
public int MaxSrsJobCount { get; set; }
}
public class PrimaryAction
{
public string ConnectionString { get; set; }
public Settings2 Settings { get; set; }
}
public class Settings3
{
public string LeadTimeInSeconds { get; set; }
public int MaxSrsJobCount { get; set; }
}
public class ErrorAction
{
public string ConnectionString { get; set; }
public string EntityPath { get; set; }
public Settings3 Settings { get; set; }
}
public class ScheduledJob
{
public string JobName { get; set; }
public PrimaryAction PrimaryAction { get; set; }
public ErrorAction ErrorAction { get; set; }
}
public class RootObject
{
public List<JobProcessor> JobProcessors { get; set; }
public List<ScheduledJob> ScheduledJobs { get; set; }
}
Hope this will help.
Thank you
I'm facing some problems with the read of a JSON file, which is this one:
{
"giocatori": [
{
"Giocatore": "124",
"Cognome": "DE SANCTIS",
"Ruolo": "P",
"Squadra": "ROM"
},
{
"Giocatore": "140",
"Cognome": "MIRANTE",
"Ruolo": "P",
"Squadra": "PAR"
},
{
"Giocatore": "156",
"Cognome": "SKORUPSKI",
"Ruolo": "P",
"Squadra": "ROM"
}
],
"success": 1
}
What I want to get from this PHP is an List, where the Player's class with this attributes;
public string Giocatore;
public string Cognome;
public string Ruolo;
public string Squadra;
I don't know why, but I face some problems with the Microsoft.Json library, in particular with Json.DeserializeObject> method, which is not able to read that web page. Can you provide some hint how to obtain a List in C# of Player ? Thank you so much for your support !
Go to http://json2csharp.com/, post your JSON there, and get the following classes:
public class Giocatori
{
public string Giocatore { get; set; }
public string Cognome { get; set; }
public string Ruolo { get; set; }
public string Squadra { get; set; }
}
public class RootObject
{
public List<Giocatori> giocatori { get; set; }
public int success { get; set; }
}
To deserialize your JSON string with JavaScriptSerializer, do:
var root = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(jsonString);
var list = root.giocatori;
To deserialize your JSON string with Json.NET, a widely used, free, open source JSON serializer, download and install it according to the instructions on the home page and do:
var root = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsonString);
var list = root.giocatori;
I make a web request in Silverlight for windows phone. And this is the responce.
{"result": {
"account": null,
"checkInfo": null,
"command": null,
"shifts": [
{
"description": "17:45 - 17:55 work shift",
"id": 5459,
"venueId": 132
}]}}
I use Newtonsoft.Json.dll and my purpose is to catch the array - shifts.
JObject obj = JObject.Parse(StringShifts);
JArray sh = (JArray)obj["shifts"];
But every time sh value is null. What i'm i doing wrong? Thank you in advance.
The other way around is: (This is very helpful, if you are doing more operations like this in your project)
Create these classes in your project
public class Shift
{
public string description { get; set; }
public int id { get; set; }
public int venueId { get; set; }
}
public class Result
{
public object account { get; set; }
public object checkInfo { get; set; }
public object command { get; set; }
public List<Shift> shifts { get; set; }
}
public class RootObject
{
public Result result { get; set; }
}
And then in your code
var rootObject = JsonConvert.DeserializeObject<RootObject>(StringShifts);
foreach(var shift in rootObject.result.shifts)
{
Console.Write(shift.description);
}
This way you can have more control on your json response data. But L.B 's answer if it is one time process in your app.
var obj = (JObject)JsonConvert.DeserializeObject(json);
foreach (var shift in obj["result"]["shifts"])
{
Console.WriteLine((string)shift["description"]);
}
You are missing the root results node; this is how you should use it:
JArray sh = (JArray)obj["result"]["shifts"];
Also, do note that there is a missing } in the end of your JSON sample above!