Deserializing JSON from TD Ameritrade - c#

I am pulling in quote data from TD Ameritrade's API, and it's generating the following JSON:
{
"AAPL": {
"52WkHigh": 145.09,
"52WkLow": 53.1525,
"askId": "P",
"askPrice": 121.08,
"askSize": 1700,
"assetMainType": "EQUITY",
"assetType": "EQUITY",
"bidId": "P",
"bidPrice": 121.06,
"bidSize": 600,
"bidTick": " ",
"closePrice": 121.03,
"cusip": "037833100",
"delayed": "false",
"description": "Apple Inc. - Common Stock",
"digits": 4,
"divAmount": 0.82,
"divDate": "2021-02-05 00:00:00.000",
"divYield": 0.68,
"exchange": "q",
"exchangeName": "NASD",
"highPrice": 121.17,
"lastId": "D",
"lastPrice": 121.08,
"lastSize": 200,
"lowPrice": 119.16,
"marginable": "true",
"mark": 121.03,
"markChangeInDouble": 0.0,
"markPercentChangeInDouble": 0.0,
"nAV": 0.0,
"netChange": 0.05,
"netPercentChangeInDouble": 0.0413,
"openPrice": 120.4,
"peRatio": 32.9702,
"quoteTimeInLong": 1615597198023,
"regularMarketLastPrice": 121.03,
"regularMarketLastSize": 7,
"regularMarketNetChange": 0.0,
"regularMarketPercentChangeInDouble": 0.0,
"regularMarketTradeTimeInLong": 1615582801729,
"securityStatus": "Normal",
"shortable": "true",
"symbol": "AAPL",
"totalVolume": 88105050,
"tradeTimeInLong": 1615597198932,
"volatility": 0.0085
}
}
Class created from JSON:
public class Quote
{
public float _52WkHigh { get; set; }
public float _52WkLow { get; set; }
public string askId { get; set; }
public float askPrice { get; set; }
public int askSize { get; set; }
public string assetMainType { get; set; }
public string assetType { get; set; }
public string bidId { get; set; }
public float bidPrice { get; set; }
public int bidSize { get; set; }
public string bidTick { get; set; }
public float closePrice { get; set; }
public string cusip { get; set; }
public string delayed { get; set; }
public string description { get; set; }
public int digits { get; set; }
public float divAmount { get; set; }
public string divDate { get; set; }
public float divYield { get; set; }
public string exchange { get; set; }
public string exchangeName { get; set; }
public float highPrice { get; set; }
public string lastId { get; set; }
public float lastPrice { get; set; }
public int lastSize { get; set; }
public float lowPrice { get; set; }
public string marginable { get; set; }
public float mark { get; set; }
public float markChangeInDouble { get; set; }
public float markPercentChangeInDouble { get; set; }
public float nAV { get; set; }
public float netChange { get; set; }
public float netPercentChangeInDouble { get; set; }
public float openPrice { get; set; }
public float peRatio { get; set; }
public long quoteTimeInLong { get; set; }
public float regularMarketLastPrice { get; set; }
public int regularMarketLastSize { get; set; }
public float regularMarketNetChange { get; set; }
public float regularMarketPercentChangeInDouble { get; set; }
public long regularMarketTradeTimeInLong { get; set; }
public string securityStatus { get; set; }
public string shortable { get; set; }
public string symbol { get; set; }
public int totalVolume { get; set; }
public long tradeTimeInLong { get; set; }
public float volatility { get; set; }
}
I am calling a Python Script to get the JSON data, which then redirects to my C# app.
However, when I deserialize it, no data is populating:
public void GetQuotes(string symbol)
{
var errors = "";
var results = "";
this.psi.Arguments = $"\"{this.script}\" -q {symbol}";
Quote quote;
using (var process = Process.Start(psi))
{
errors = process.StandardError.ReadToEnd();
results = process.StandardOutput.ReadToEnd();
Debug.Print(results);
quote = JsonConvert.DeserializeObject<Quote>(results);
}
MessageBox.Show(quote.symbol);
}
I have been able to deserialize Json with relatively consistent success, but I can't figure out why I'm loading in blank objects from this JSON.

You need to create a root object that contains your Quote object.
public class RootObject
{
public Quote AAPL { get;set;}
}
and deserialize to this,
var rootObject = JsonConvert.DeserializeObject<RootObject>(results);
Quote quote = rootObject.AAPL;
When you deserialize to Quote, you are getting nulls because there is no property in the original json that matches with any of the Quote properties. Since your JSON contains 1 property (AAPL) and its value is of type Quote, you have to deserialize to RootObject.
Based on your point on variable key, you should deserialize to Dictionary<string, Quote>.
var obj = JsonConvert.DeserializeObject<Dictionary<string, Quote>>(results);
Quote quote = obj.FirstOrDefault().Value;
You can also list all keys and use foreach loop but if you know there will always be only one key, FirstOrDefault() will work as well.

Thanks to Jawad for the quick hint. Because 'AAPL' is an ever-changing key, I had to deserialize the JSON into a Dictionary<string, Quote> to get the data populating:
public void GetQuotes(string symbol)
{
var errors = "";
var results = "";
this.psi.Arguments = $"\"{this.script}\" -q {symbol}";
Dictionary<string, Quote> quotes;
using (var process = Process.Start(psi))
{
errors = process.StandardError.ReadToEnd();
results = process.StandardOutput.ReadToEnd();
Debug.Print(results);
quotes = JsonConvert.DeserializeObject<Dictionary<string, Quote>>(results);
}
}

Related

How to parse "temp" from Json in C#?

I need to get "temp", name and description out of this JSON format. I can get some of these out but not all, I went through the questions but I could not get a specific answer.
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(string.Format("https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=XXX"));
WebReq.Method = "GET";
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
Console.WriteLine(WebResp.StatusCode);
Console.WriteLine(WebResp.Server);
string jsonString;
//modified from your code since the using statement disposes the stream
//automatically when done
using (Stream stream = WebResp.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8);
jsonString = reader.ReadToEnd();
}
List<Item> items = JsonConvert.DeserializeObject<List<Item>>(jsonString);
foreach (var item in obj)
{
}
JSON FORMAT:
{
"coord":{
"lon":-0.13,
"lat":51.51
},
"weather":[
{
"id":300,
"main":"Drizzle",
"description":"light intensity drizzle",
"icon":"09d"
}
],
"base":"stations",
"main":{
"temp":280.32,
"pressure":1012,
"humidity":81,
"temp_min":279.15,
"temp_max":281.15
},
"visibility":10000,
"wind":{
"speed":4.1,
"deg":80
},
"clouds":{
"all":90
},
"dt":1485789600,
"sys":{
"type":1,
"id":5091,
"message":0.0103,
"country":"GB",
"sunrise":1485762037,
"sunset":1485794875
},
"id":2643743,
"name":"London",
"cod":200
}
You will need to use Json.NET (NuGet). Then, create a model for the json, you can use some online tools like QuickType and Json Editor Online to help you converting Json to Object. Then, use the model with the Json.NET to Deserialize it (in other word, mapping the Json to the Model).
Then, use the new created object to access the json values.
Here is an example of your Json (Using Json.NET):
Model :
public class WeatherCast
{
[JsonProperty("coord")]
public Coord Coord { get; set; }
[JsonProperty("weather")]
public Weather[] Weather { get; set; }
[JsonProperty("base")]
public string Base { get; set; }
[JsonProperty("main")]
public Main Main { get; set; }
[JsonProperty("visibility")]
public long Visibility { get; set; }
[JsonProperty("wind")]
public Wind Wind { get; set; }
[JsonProperty("clouds")]
public Clouds Clouds { get; set; }
[JsonProperty("dt")]
public long Dt { get; set; }
[JsonProperty("sys")]
public Sys Sys { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("cod")]
public long Cod { get; set; }
}
public class Weather
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("main")]
public string Main { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("icon")]
public string Icon { get; set; }
}
public class Clouds
{
[JsonProperty("all")]
public long All { get; set; }
}
public class Coord
{
[JsonProperty("lon")]
public double Lon { get; set; }
[JsonProperty("lat")]
public double Lat { get; set; }
}
public class Main
{
[JsonProperty("temp")]
public double Temp { get; set; }
[JsonProperty("pressure")]
public long Pressure { get; set; }
[JsonProperty("humidity")]
public long Humidity { get; set; }
[JsonProperty("temp_min")]
public double TempMin { get; set; }
[JsonProperty("temp_max")]
public double TempMax { get; set; }
}
public class Sys
{
[JsonProperty("type")]
public long Type { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("message")]
public double Message { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("sunrise")]
public long Sunrise { get; set; }
[JsonProperty("sunset")]
public long Sunset { get; set; }
}
public class Wind
{
[JsonProperty("speed")]
public double Speed { get; set; }
[JsonProperty("deg")]
public long Deg { get; set; }
}
Then, using Json.NET you do this :
var json = "{\"coord\":{\"lon\":-0.13,\"lat\":51.51},\"weather\":[{\"id\":300,\"main\":\"Drizzle\",\"description\":\"light intensity drizzle\",\"icon\":\"09d\"}],\"base\":\"stations\",\"main\":{\"temp\":280.32,\"pressure\":1012,\"humidity\":81,\"temp_min\":279.15,\"temp_max\":281.15},\"visibility\":10000,\"wind\":{\"speed\":4.1,\"deg\":80},\"clouds\":{\"all\":90},\"dt\":1485789600,\"sys\":{\"type\":1,\"id\":5091,\"message\":0.0103,\"country\":\"GB\",\"sunrise\":1485762037,\"sunset\":1485794875},\"id\":2643743,\"name\":\"London\",\"cod\":200}";
var forecast = JsonConvert.DeserializeObject<WeatherCast>(json);
var temp = forecast.Main.Temp;
var name = forecast.Name;
var description = forecast.Weather[0].Description;

How to convert string to Newtonsoft.Json.Linq.JObject

Im still newbie and learning some API calls. Just dont know why code dont convert from string to Newtonsoft.Json.Linq.JObject.
WebRequest request = WebRequest.Create("https://api.pandascore.co/lol/champions?filter[name]=Brand&token==mytoken");
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string responseFromServer = reader.ReadToEnd();
JObject parsedString = JObject.Parse(responseFromServer);
Champions champion = parsedString.ToObject<Champions>();
return View(champion);
and in debug mode responseFromServer is a string
and result is looking ok, but this dont convert to object. parsedString = null.
Newtonsoft.Json.JsonReaderException: „Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path
Champions class look like:
public class Champions
{
public List<string> videogame_versions { get; set; }
public double spellblockperlevel { get; set; }
public double spellblock { get; set; }
public string name { get; set; }
public double mpregenperlevel { get; set; }
public double mpregen { get; set; }
public double mpperlevel { get; set; }
public double mp { get; set; }
public double movespeed { get; set; }
public string image_url { get; set; }
public int id { get; set; }
public double hpregenperlevel { get; set; }
public double hpregen { get; set; }
public double hpperlevel { get; set; }
public double hp { get; set; }
public double critperlevel { get; set; }
public double crit { get; set; }
public string big_image_url { get; set; }
public double attackspeedperlevel { get; set; }
public object attackspeedoffset { get; set; }
public double attackrange { get; set; }
public double attackdamageperlevel { get; set; }
public double attackdamage { get; set; }
public double armorperlevel { get; set; }
public double armor { get; set; }
}
}
my JSON string looks like :
[
{
"videogame_versions": [
"9.10.1",
"9.9.1",
"9.8.1",
"9.7.2",
"9.7.1",
"9.6.1",
"9.5.1",
"9.4.1",
"9.3.1",
"9.2.1",
"9.1.1",
"8.24.1",
"8.23.1",
"8.22.1"
],
"spellblockperlevel": 0.5,
"spellblock": 30,
"name": "Brand",
"mpregenperlevel": 0.6,
"mpregen": 10.665,
"mpperlevel": 21,
"mp": 469,
"movespeed": 340,
"image_url": "https://cdn.pandascore.co/images/lol/champion/image/7aa667709a7ce82e45c459e3df2d160a.png",
"id": 2347,
"hpregenperlevel": 0.55,
"hpregen": 5.5,
"hpperlevel": 88,
"hp": 519.68,
"critperlevel": 0,
"crit": 0,
"big_image_url": "https://cdn.pandascore.co/images/lol/champion/big_image/8ba7fd90e7c250b2dcc3183205ad6d94.jpg",
"attackspeedperlevel": 1.36,
"attackspeedoffset": null,
"attackrange": 550,
"attackdamageperlevel": 3,
"attackdamage": 57.04,
"armorperlevel": 3.5,
"armor": 21.88
}
]
offers 6 kingdoms and broken wheel for help
The trick here is to deserialize into a List<Champions> as your root level JSON data is an array.
public static class Program
{
private static void Main(string[] args)
{
string data = #"
[
{
'videogame_versions': [
'9.10.1',
'9.9.1',
'9.8.1',
'9.7.2',
'9.7.1',
'9.6.1',
'9.5.1',
'9.4.1',
'9.3.1',
'9.2.1',
'9.1.1',
'8.24.1',
'8.23.1',
'8.22.1'
],
'spellblockperlevel': 0.5,
'spellblock': 30,
'name': 'Brand',
'mpregenperlevel': 0.6,
'mpregen': 10.665,
'mpperlevel': 21,
'mp': 469,
'movespeed': 340,
'image_url': 'https://cdn.pandascore.co/images/lol/champion/image/7aa667709a7ce82e45c459e3df2d160a.png',
'id': 2347,
'hpregenperlevel': 0.55,
'hpregen': 5.5,
'hpperlevel': 88,
'hp': 519.68,
'critperlevel': 0,
'crit': 0,
'big_image_url': 'https://cdn.pandascore.co/images/lol/champion/big_image/8ba7fd90e7c250b2dcc3183205ad6d94.jpg',
'attackspeedperlevel': 1.36,
'attackspeedoffset': null,
'attackrange': 550,
'attackdamageperlevel': 3,
'attackdamage': 57.04,
'armorperlevel': 3.5,
'armor': 21.88
}
]
";
List<Champions> champions = JsonConvert.DeserializeObject<List<Champions>>(data);
}
public class Champions
{
public List<string> videogame_versions { get; set; }
public double spellblockperlevel { get; set; }
public double spellblock { get; set; }
public string name { get; set; }
public double mpregenperlevel { get; set; }
public double mpregen { get; set; }
public double mpperlevel { get; set; }
public double mp { get; set; }
public double movespeed { get; set; }
public string image_url { get; set; }
public int id { get; set; }
public double hpregenperlevel { get; set; }
public double hpregen { get; set; }
public double hpperlevel { get; set; }
public double hp { get; set; }
public double critperlevel { get; set; }
public double crit { get; set; }
public string big_image_url { get; set; }
public double attackspeedperlevel { get; set; }
public object attackspeedoffset { get; set; }
public double attackrange { get; set; }
public double attackdamageperlevel { get; set; }
public double attackdamage { get; set; }
public double armorperlevel { get; set; }
public double armor { get; set; }
}
}
JObject represents a JSON Object which is known as { /*key value pairs*/ } and what it actually should be is JArray
If you don't want to specify as a JSON Object or a JSON Array, you can use JToken instead.
If your json in array then you must need to convert List object
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var json = #"[
{
'videogame_versions': [
'9.10.1',
'9.9.1',
'9.8.1',
'9.7.2',
'9.7.1',
'9.6.1',
'9.5.1',
'9.4.1',
'9.3.1',
'9.2.1',
'9.1.1',
'8.24.1',
'8.23.1',
'8.22.1'
],
'spellblockperlevel': 0.5,
'spellblock': 30,
'name': 'Brand',
'mpregenperlevel': 0.6,
'mpregen': 10.665,
'mpperlevel': 21,
'mp': 469,
'movespeed': 340,
'image_url': 'https://cdn.pandascore.co/images/lol/champion/image/7aa667709a7ce82e45c459e3df2d160a.png',
'id': 2347,
'hpregenperlevel': 0.55,
'hpregen': 5.5,
'hpperlevel': 88,
'hp': 519.68,
'critperlevel': 0,
'crit': 0,
'big_image_url': 'https://cdn.pandascore.co/images/lol/champion/big_image/8ba7fd90e7c250b2dcc3183205ad6d94.jpg',
'attackspeedperlevel': 1.36,
'attackspeedoffset': null,
'attackrange': 550,
'attackdamageperlevel': 3,
'attackdamage': 57.04,
'armorperlevel': 3.5,
'armor': 21.88
}
]";
List<Champions> champions = JsonConvert.DeserializeObject<List<Champions>>(json);
}
}

MlContext doesn't understand the type of my temperature

I'm Beginner at ML.NET and I have a little problem with my data. When I put them inside mlContext.Fit(...); Here's the error I received:
Column 'Temperature' has values of I4which is not the same as earlier observed type of R4.
Here's my code:
try
{
var mlContext = new MLContext();
var reader = mlContext.Data.CreateTextReader<TrainData>(separatorChar: ',', hasHeader: false);
var trainData = _context.Datas.Last();
IDataView trainingdataView = reader.Read(Path.Combine(hostingEnvironment.WebRootPath, "data010220192341.txt"));
var pipeline = mlContext.Transforms.Conversion.MapValueToKey("Delay")
.Append(mlContext.Transforms.Categorical.OneHotEncoding("StationDepart"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("StationArrival"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("Day"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("Train"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("WeatherText"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("HasPrecipitation"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("PrecipitationType"))
.Append(mlContext.Transforms.Concatenate("Features", "StationDepart", "StationArrival", "Day", "Train", "WeatherText", "Temperature", "Humidity", "HasPrecipitation", "PrecipitationType", "Time"))
.Append(mlContext.MulticlassClassification.Trainers.StochasticDualCoordinateAscent(labelColumn: "Delay", featureColumn: "Features"))
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedTime"));
var model = pipeline.Fit(trainingdataView);
var prediction = model.CreatePredictionEngine<TrainData, TrainPrediction>(mlContext).Predict(
new TrainData()
{
StationDepart = "Charleroi-Sud",
StationArrival = "Mons",
Day = "Friday",
Train = "BE.NMBS.IC3825",
WeatherText = "Partly cloudy",
Temperature = -1,
Humidity=0,
HasPrecipitation = false,
PrecipitationType=null,
Time=0444
});
return prediction.PredictedTime.ToString();
}
catch (Exception e)
{
return e.Message;
}
So when I get the Data on a text file, after that, I encode string Column and after I try to Train the model but it's at this moment I received the error.
and my data are:
Charleroi-Sud,Mons,Thursday,BE.NMBS.IC3831,Partly
sunny,-2,0,False,,1044,0
Charleroi-Sud,Mons,Thursday,BE.NMBS.IC932,Mostly cloudy,-2,0,False,,1112,0
Charleroi-Sud,Mons,Thursday,BE.NMBS.IC3832,Mostly cloudy,-1,0,False,,1144,0
Charleroi-Sud,Mons,Thursday,BE.NMBS.IC933,Cloudy,-1,0,False,,1212,0
Charleroi-Sud,Mons,Thursday,BE.NMBS.IC3842,Mostly cloudy,-1,0,False,,2144,0
Charleroi-Sud,Mons,Thursday,BE.NMBS.IC943,Mostly cloudy,-1,0,False,,2212,0
Charleroi-Sud,Mons,Thursday,BE.NMBS.IC3843,Mostly cloudy,-1,0,False,,2247,0
Charleroi-Sud,Mons,Friday,BE.NMBS.IC3825,Partly cloudy,-1,0,False,,0444,0
Charleroi-Sud,Mons,Friday,BE.NMBS.IC3826,Mostly cloudy,-1,0,False,,0544,0
Charleroi-Sud,Mons,Friday,BE.NMBS.IC927,Mostly cloudy,-1,0,False,,0612,0
So as you can see, there is every ',' between data and the temperature is a int.
And inside the TrainData, that done like that:
public class TrainData
{
[LoadColumn(0)]
public string StationDepart { get; set; }
[LoadColumn(1)]
public string StationArrival { get; set; }
[LoadColumn(2)]
public string Day { get; set; }
[LoadColumn(3)]
public string Train { get; set; }
[LoadColumn(4)]
public string WeatherText { get; set; }
[LoadColumn(5)]
public int Temperature { get; set; }
[LoadColumn(6)]
public int Humidity { get; set; }
[LoadColumn(7)]
public bool HasPrecipitation { get; set; }
[LoadColumn(8)]
public string PrecipitationType { get; set; }
[LoadColumn(9)]
public int Time { get; set; }
[LoadColumn(10)]
public int Delay { get; set; }
}
The problem was that the Time, the delay and the temperature need to be in float and not in int.
public class TrainData
{
[LoadColumn(0)]
public string StationDepart { get; set; }
[LoadColumn(1)]
public string StationArrival { get; set; }
[LoadColumn(2)]
public string Day { get; set; }
[LoadColumn(3)]
public string Train { get; set; }
[LoadColumn(4)]
public string WeatherText { get; set; }
[LoadColumn(5)]
public float Temperature { get; set; }
[LoadColumn(6)]
public float Humidity { get; set; }
[LoadColumn(7)]
public bool HasPrecipitation { get; set; }
[LoadColumn(8)]
public string PrecipitationType { get; set; }
[LoadColumn(9)]
public float Time { get; set; }
[LoadColumn(10)]
public float Delay { get; set; }
}

C# - How convert json string to class

How can I convert my json-string to class
this is my json
{
"$id": "1",
"Result": {
"$id": "2",
"dateTime": 23821964,
"list": [{
"$id": "3",
"UserId": 302,
"UID": "302_UID",
"Title": "شیدکو",
"Sender": "شیدکو",
"Answer": "",
"Comment": "test 2",
"ProductTitle": null,
"CommentId": 77,
"Logo": "http://example.com/Commercial/User/302/Logo/tmpF0BF.jpg",
"Date": 24302057,
"AnswerDate": -2123661683,
"AnswerEdit": false,
"CommentEdit": false,
"ForfeitCount": 0,
"RewardCount": 0,
"ThisCountReport": 2,
"Reported": [{
"$id": "4",
"BlockerId": 355,
"Title": "محتوای غیر اخلاقی",
"Date": -19527396,
"ForfeitCount": 0,
"RewardCount": 0
}, {
"$id": "5",
"BlockerId": 355,
"Title": "محتوای غیر مرتبط",
"Date": -19527382,
"ForfeitCount": 0,
"RewardCount": 0
}],
"Gem": 0
}, {
"$id": "6",
"UserId": 302,
"UID": "302_UID",
"Title": "شیدکو",
"Sender": "شیدکو",
"Answer": "",
"Comment": "test 2",
"ProductTitle": null,
"CommentId": 77,
"Logo": "http://example.com/Commercial/User/302/Logo/tmpF0BF.jpg",
"Date": 24302057,
"AnswerDate": -2123661683,
"AnswerEdit": false,
"CommentEdit": false
}]
},
"StatusCode": "Created",
"Description": null
}
And I do these step, but nothing happens
JObject json1 = JObject.Parse(strMyJson);
_CommentAdmindto flight = Newtonsoft.Json.JsonConvert.DeserializeObject<_CommentAdmindto>(json1.ToString());
_CommentAdmindto deserializedProduct = JsonConvert.DeserializeObject<_CommentAdmindto>(json);
_CommentAdmindto deserializedProduct1 = ConvertJsonToClass<_CommentAdmindto>(strMyJson);
JsonSerializer serializer = new JsonSerializer();
_CommentAdmindto p = (_CommentAdmindto)serializer.Deserialize(new JTokenReader(strMyJson), typeof(_CommentAdmindto));
And here is my class and function:
public static T ConvertJsonToClass<T>( string json)
{
System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
return serializer.Deserialize<T>(json);
}
}
public class _CommentAdmindto
{
public long dateTime { get; set; }
public IQueryable<CommentDtoAdmin> list { get; set; }
}
public class CommentDtoAdmin
{
public long UserId { get; set; }
public string UID { get; set; }
public string Title { get; set; }
public string Sender { get; set; }
public string Answer { get; set; }
public string Comment { get; set; }
public string ProductTitle { get; set; }
public long CommentId { get; set; }
public string Logo { get; set; }
public long Date { get; set; }
public long AnswerDate { get; set; }
public bool AnswerEdit { get; set; }
public bool CommentEdit { get; set; }
}
Your model should be similar to this (For invalid c# names, you can use JsonProperty attribute) :
public class Reported
{
[JsonProperty("$id")]
public string id { get; set; }
public int BlockerId { get; set; }
public string Title { get; set; }
public int Date { get; set; }
public int ForfeitCount { get; set; }
public int RewardCount { get; set; }
}
public class List
{
[JsonProperty("$id")]
public string id { get; set; }
public int UserId { get; set; }
public string UID { get; set; }
public string Title { get; set; }
public string Sender { get; set; }
public string Answer { get; set; }
public string Comment { get; set; }
public object ProductTitle { get; set; }
public int CommentId { get; set; }
public string Logo { get; set; }
public int Date { get; set; }
public int AnswerDate { get; set; }
public bool AnswerEdit { get; set; }
public bool CommentEdit { get; set; }
public int ForfeitCount { get; set; }
public int RewardCount { get; set; }
public int ThisCountReport { get; set; }
public List<Reported> Reported { get; set; }
public int Gem { get; set; }
}
public class Result
{
[JsonProperty("$id")]
public string id { get; set; }
public int dateTime { get; set; }
public List<List> list { get; set; }
}
public class RootObject
{
[JsonProperty("$id")]
public string id { get; set; }
public Result Result { get; set; }
public string StatusCode { get; set; }
public object Description { get; set; }
}
Now you can deserialize as
var result = JsonConvert.DeserializeObject<RootObject>(jsonstring);
BTW: http://json2csharp.com/ can help to guess your model when working with json.
You seem to be trying to deserialize in a lot of different ways but you don't have a full structure to actually match the json. You miss the outer class (representing the full object) and at least Newtonsoft.Json cannot deserialize to an IQueryable so I changed that to IEnumerable.
string strMyJson = "{\"$id\":\"1\",\"Result\":{\"$id\":\"2\",\"dateTime\":23826985,\"list\":[{\"$id\":\"3\",\"UserId\":302,\"UID\":\"302_UID\",\"Title\":\"شیدکو\",\"Sender\":\"شیدکو\",\"Answer\":\"\",\"Comment\":\"test 2\",\"ProductTitle\":null,\"CommentId\":77,\"Logo\":\"http://www.domain.com/Commercial/User/302/Logo/tmpF0BF.jpg\",\"Date\":24307078,\"AnswerDate\":-2123656662,\"AnswerEdit\":false,\"CommentEdit\":false,\"ForfeitCount\":0,\"RewardCount\":0,\"ThisCountReport\":2,\"Reported\":[{\"$id\":\"4\",\"BlockerId\":355,\"Title\":\"محتوای غیر اخلاقی\",\"Date\":-19527396,\"ForfeitCount\":0,\"RewardCount\":0},{\"$id\":\"5\",\"BlockerId\":355,\"Title\":\"محتوای غیر مرتبط\",\"Date\":-19527382,\"ForfeitCount\":0,\"RewardCount\":0}],\"Gem\":0},{\"$id\":\"6\",\"UserId\":302,\"UID\":\"302_UID\",\"Title\":\"شیدکو\",\"Sender\":\"شیدکو\",\"Answer\":\"\",\"Comment\":\"test 2\",\"ProductTitle\":null,\"CommentId\":77,\"Logo\":\"http://www.domain.com/Commercial/User/302/Logo/tmpF0BF.jpg\",\"Date\":24307078,\"AnswerDate\":-2123656662,\"AnswerEdit\":false,\"CommentEdit\":false}],\"StatusCode\":\"Created\",\"Description\":null}}";
var result = JsonConvert.DeserializeObject<Wrapper>(strMyJson);
with classes looking like this:
public class Wrapper
{
public _CommentAdmindto Result { get; set; }
}
public class _CommentAdmindto
{
public long dateTime { get; set; }
public IEnumerable<CommentDtoAdmin> list { get; set; }
}
CommentDtoAdmin is looking the same.
Though I must say that this only helps you with the deserialization.
Firstly, the $id" properties are synthetic properties added by Json.NET to track and preserve multiple references to the same object. For details, see PreserveReferencesHandling setting.
Thus, if you temporarily remove the "$id" properties, you can upload your JSON to http://json2csharp.com/ and get the following data model:
public class Reported
{
public int BlockerId { get; set; }
public string Title { get; set; }
public int Date { get; set; }
public int ForfeitCount { get; set; }
public int RewardCount { get; set; }
}
public class CommentDtoAdmin
{
public int UserId { get; set; }
public string UID { get; set; }
public string Title { get; set; }
public string Sender { get; set; }
public string Answer { get; set; }
public string Comment { get; set; }
public object ProductTitle { get; set; }
public int CommentId { get; set; }
public string Logo { get; set; }
public int Date { get; set; }
public int AnswerDate { get; set; }
public bool AnswerEdit { get; set; }
public bool CommentEdit { get; set; }
public int ForfeitCount { get; set; }
public int RewardCount { get; set; }
public int ThisCountReport { get; set; }
public List<Reported> Reported { get; set; }
public int Gem { get; set; }
}
public class Result
{
public int dateTime { get; set; }
public List<CommentDtoAdmin> list { get; set; }
}
public class RootObject
{
public Result Result { get; set; }
public string StatusCode { get; set; }
public string Description { get; set; }
}
I then modified the returned model as follows:
I used the name CommentDtoAdmin for the list type.
I set the type of the Description property to string.
Now your JSON can be deserialized and re-serialized as follows:
var settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
};
var root = JsonConvert.DeserializeObject<RootObject>(json1, settings);
var json2 = JsonConvert.SerializeObject(root, Formatting.Indented, settings);
Note that Json.NET has no built-in logic for deserializing the interface IQueryable<T> to a concrete type, so I had to leave the property as public List<CommentDtoAdmin> list { get; set; }. You can always generate a queryable from the list using AsQueryable():
var queryable = root.Result.list.AsQueryable();
Sample fiddle.
I think you json string does not have correct syntax. It looks like a ']' (end of Array) and a final '}' is missing.
That's what the Visual Studio editor told me when making a json file out of your string after removing all the '\'

Trouble parsing forecast.io weather data with Json.Net

I am relatively new to JSON and using an API forecast.io. It returns the JSON below, which I need to parse.
"daily":{
"summary":"Drizzle on Monday and Tuesday, with temperatures bottoming out at 91°F on Monday.","icon":"rain",
"data":[{
"time":1463770800,"summary":"Clear throughout the day.","icon":"clearday","sunriseTime":1463788956,"sunsetTime":1463839653,"moonPhase":0.48,"precipIntensity":0,"precipIntensityMax":0,"precipProbability":0,"temperatureMin":63.06,"temperatureMinTime":1463785200,"temperatureMax":95.23,"temperatureMaxTime":1463824800,"apparentTemperatureMin":63.06,"apparentTemperatureMinTime":1463785200,"apparentTemperatureMax":90.3,"apparentTemperatureMaxTime":1463824800,"dewPoint":37.34,"humidity":0.25,"windSpeed":3.44,"windBearing":22,"cloudCover":0,"pressure":1002.14,"ozone":283.7}
I extracted the "daily" portion successfully, but I could not get the "data" inside the "daily". I need to have the details, i.e. summary, time, icon, etc. I'd really appreciate some help.
Here is my C# code:
var test = new System.Net.WebClient().DownloadString("https://api.forecast.io/forecast/f2857958690caafc67d0dfba402c1f57/" + Latitude + "," + Longitude);
var json = JObject.Parse(test);
var daily = json.ToObject<DailyWeatherDTO>();
public class DailyWeatherDTO
{
public DailyWeatherData daily { get; set; }
}
public class DailyWeatherData
{
public daily data { get; set; }
}
public class daily
{
public string time { get; set; }
public String summary { get; set; }
public String icon { get; set; }
public String precipIntensity { get; set; }
public String precipProbability { get; set; }
public string sunriseTime { get; set; }
public string sunsetTime { get; set; }
public string moonPhase { get; set; }
public string precipIntensityMax { get; set; }
public string temperatureMin { get; set; }
public string temperatureMinTime { get; set; }
public string temperatureMax { get; set; }
public string temperatureMaxTime { get; set; }
public string apparentTemperatureMin { get; set; }
public string apparentTemperatureMinTime { get; set; }
public string apparentTemperatureMax { get; set; }
public string apparentTemperatureMaxTime { get; set; }
public string dewPoint { get; set; }
public string humidity { get; set; }
public string windSpeed { get; set; }
public string windBearing { get; set; }
public string cloudCover { get; set; }
public string pressure { get; set; }
public string ozone { get; set; }
}
First of all, the JSON you posted is not valid as shown. Specifically, you are missing a closing square bracket and curly brace at the end; plus, the whole thing needs to be enclosed in another pair of curly braces to be valid. Here is the corrected version, reformatted for readability:
{
"daily": {
"summary": "Drizzle on Monday and Tuesday, with temperatures bottoming out at 91°F on Monday.",
"icon": "rain",
"data": [
{
"time": 1463770800,
"summary": "Clear throughout the day.",
"icon": "clearday",
"sunriseTime": 1463788956,
"sunsetTime": 1463839653,
"moonPhase": 0.48,
"precipIntensity": 0,
"precipIntensityMax": 0,
"precipProbability": 0,
"temperatureMin": 63.06,
"temperatureMinTime": 1463785200,
"temperatureMax": 95.23,
"temperatureMaxTime": 1463824800,
"apparentTemperatureMin": 63.06,
"apparentTemperatureMinTime": 1463785200,
"apparentTemperatureMax": 90.3,
"apparentTemperatureMaxTime": 1463824800,
"dewPoint": 37.34,
"humidity": 0.25,
"windSpeed": 3.44,
"windBearing": 22,
"cloudCover": 0,
"pressure": 1002.14,
"ozone": 283.7
}
]
}
}
To be able to get all the data, your class structure needs to match the structure of the JSON. Assuming the above represents the complete JSON, here is what your classes should look like. In particular, notice the data property of the DailyWeatherData class is defined as a list of items (not a single object), which corresponds to the square brackets for the data property in the JSON.
public class DailyWeatherDTO // root-level container object
{
public DailyWeatherData daily { get; set; }
}
public class DailyWeatherData
{
public string summary { get; set; }
public string icon { get; set; }
public List<WeatherItem> data { get; set; }
}
public class WeatherItem
{
public int time { get; set; }
public string summary { get; set; }
public string icon { get; set; }
public int sunriseTime { get; set; }
public int sunsetTime { get; set; }
public double moonPhase { get; set; }
public int precipIntensity { get; set; }
public int precipIntensityMax { get; set; }
public int precipProbability { get; set; }
public double temperatureMin { get; set; }
public int temperatureMinTime { get; set; }
public double temperatureMax { get; set; }
public int temperatureMaxTime { get; set; }
public double apparentTemperatureMin { get; set; }
public int apparentTemperatureMinTime { get; set; }
public double apparentTemperatureMax { get; set; }
public int apparentTemperatureMaxTime { get; set; }
public double dewPoint { get; set; }
public double humidity { get; set; }
public double windSpeed { get; set; }
public int windBearing { get; set; }
public int cloudCover { get; set; }
public double pressure { get; set; }
public double ozone { get; set; }
}
With this class structure, you can deserialize the JSON like this:
DailyWeatherDTO dto = JsonConvert.DeserializeObject<DailyWeatherDTO>(json);
Here is a demo: https://dotnetfiddle.net/YTBrac

Categories