How do I deserialise this JSON? - c#

I haven't done anything with JSON before... so I am probably just missing a step.
Here is an example of the JSON I want to deserialise:
{"item":{"icon":"http://services.runescape.com/m=itemdb_rs/4765_obj_sprite.gif?id=4798","icon_large":"http://services.runescape.com/m=itemdb_rs/4765_obj_big.gif?id=4798","id":4798,"type":"Ammo","typeIcon":"http://www.runescape.com/img/categories/Ammo","name":"Adamant brutal","description":"Blunt adamantite arrow...ouch","current":{"trend":"neutral","price":237},"today":{"trend":"neutral","price":0},"members":"true","day30":{"trend":"positive","change":"+1.0%"},"day90":{"trend":"negative","change":"-0.0%"},"day180":{"trend":"positive","change":"+0.0%"}}}
I put this into "Json 2 C#" and ended up creating this new .cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RSTool.Models
{
public class Current
{
public string trend { get; set; }
public int price { get; set; }
}
public class Today
{
public string trend { get; set; }
public int price { get; set; }
}
public class Day30
{
public string trend { get; set; }
public string change { get; set; }
}
public class Day90
{
public string trend { get; set; }
public string change { get; set; }
}
public class Day180
{
public string trend { get; set; }
public string change { get; set; }
}
public class Item
{
public string icon { get; set; }
public string icon_large { get; set; }
public int id { get; set; }
public string type { get; set; }
public string typeIcon { get; set; }
public string name { get; set; }
public string description { get; set; }
public Current current { get; set; }
public Today today { get; set; }
public string members { get; set; }
public Day30 day30 { get; set; }
public Day90 day90 { get; set; }
public Day180 day180 { get; set; }
}
public class RootObject
{
public Item item { get; set; }
}
}
So, I have the class. I can retrieve the JSON from its location as a string, but I really have no idea how to deserialise it... I have installed Newtonsoft.Json and have tried using PopulateObject and also Deserializer but not with any luck...
Assuming that my JSON is stored as a string called "json", how would I go about storing that query and then retrieving the item name, for example?

Use:
var deserialized = JsonConvert.DeserializeObject<RootObject>(json);
I just tested this successfully given the code you supplied.
You can then access properties of object as normal:
MessageBox.Show(deserialized.item.name);

Related

Deserializing Json from iTunes store into C# object

I have the following Json returned from iTunes (I have replaced some details for privacy such as username and review content)
{"feed":{"author":{"name":{"label":"iTunes Store"}, "uri":{"label":"http://www.apple.com/uk/itunes/"}}, "entry":[
{"author":{"uri":{"label":"https://itunes.apple.com/gb/reviews/ID"}, "name":{"label":"Username"}, "label":""}, "im:version":{"label":"3.51"}, "im:rating":{"label":"4"}, "id":{"label":"12345"}, "title":{"label":"Review title"}, "content":{"label":"Review contents", "attributes":{"type":"text"}}, "link":{"attributes":{"rel":"related", "href":"https://itunes.apple.com/gb/review?reviewid"}}, "im:voteSum":{"label":"0"}, "im:contentType":{"attributes":{"term":"Application", "label":"Application"}}, "im:voteCount":{"label":"0"}},
// more entries ...
I want to deserialize this into a class. I only need the Review Title, Review contents, and the "im:rating" (which is the number of stars). However, I'm struggling due to the nested Json and the use of keys of how to extract this data. So far I have created a class ready to deserialize, and I have AppStoreData appStoreData = JsonConvert.DeserializeObject<AppStoreData>(stringResult); to deserialize it
public class AppStoreData {
}
My problem is that I don't know what to put inside the class to get the info I need from the Json. I have tried things such as:
public string title {get; set;}
public string content {get; set;}
public string imrating {get; set;}
However this doesn't work. I also think im:rating is an invalid name in C#.
Can anyone please help? Thank you
To get around the issue with im:rating you can use a JsonProperty attribute
[JsonProperty("im:rating")]
public Id ImRating { get; set; }
The issue with converting things like Label to string property is that it's not a string but an object in the input file.
You need something like
[JsonProperty("title")]
public Id Title { get; set; }
where Id is a class
public class Id
{
[JsonProperty("label")]
public string Label { get; set; }
}
Or write a deserializer that converts it to string for you.
I would suggest trying out one of many free code generators like https://app.quicktype.io/?l=csharp or http://json2csharp.com/ to get a headstart and edit everything to your liking afterwards.
I suggest using json2csharp to convert the json to c# model and change the invalid attributes by adding JsonProperty
public class Name
{
public string label { get; set; }
}
public class Uri
{
public string label { get; set; }
}
public class Author
{
public Name name { get; set; }
public Uri uri { get; set; }
}
public class Uri2
{
public string label { get; set; }
}
public class Name2
{
public string label { get; set; }
}
public class Author2
{
public Uri2 uri { get; set; }
public Name2 name { get; set; }
public string label { get; set; }
}
public class ImVersion
{
public string label { get; set; }
}
public class ImRating
{
public string label { get; set; }
}
public class Id
{
public string label { get; set; }
}
public class Title
{
public string label { get; set; }
}
public class Attributes
{
public string type { get; set; }
}
public class Content
{
public string label { get; set; }
public Attributes attributes { get; set; }
}
public class Attributes2
{
public string rel { get; set; }
public string href { get; set; }
}
public class Link
{
public Attributes2 attributes { get; set; }
}
public class ImVoteSum
{
public string label { get; set; }
}
public class Attributes3
{
public string term { get; set; }
public string label { get; set; }
}
public class ImContentType
{
public Attributes3 attributes { get; set; }
}
public class ImVoteCount
{
public string label { get; set; }
}
public class Entry
{
public Author2 author { get; set; }
[JsonProperty(PropertyName = "im:version")]
public ImVersion imversion { get; set; }
[JsonProperty(PropertyName = "im:rating")]
public ImRating imrating { get; set; }
public Id id { get; set; }
public Title title { get; set; }
public Content content { get; set; }
public Link link { get; set; }
[JsonProperty(PropertyName = "im:voteSum")]
public ImVoteSum imvoteSum { get; set; }
[JsonProperty(PropertyName = "im:contentType")]
public ImContentType imcontentType { get; set; }
[JsonProperty(PropertyName = "im:voteCount")]
public ImVoteCount imvoteCount { get; set; }
}
public class Feed
{
public Author author { get; set; }
public List<Entry> entry { get; set; }
}
public class RootObject5
{
public Feed feed { get; set; }
}
Once the model is ready you can use JsonConvert.DeserializeObject to convert the JSON to c# object
using (StreamReader r = new StreamReader(filepath)) {
string json = r.ReadToEnd();
var newEmps = JsonConvert.DeserializeObject<RootObject5>(json);
Console.WriteLine(newEmps.feed.entry[0].imvoteCount.label);
}

Unable to correctly parse JSON body

I am successfully able to retrieve the JSON body from a URL in Visual Studio 2019 using Newtonsoft library. However I'm having difficulty in parsing out the only variable I am interested in.
I've tried to follow some guides on here that I don't seem to have either implemented correctly or haven't fully understood (I'm pretty new to this).
e.g.
Unexpected character encountered while parsing API response
RAW JSON:
{"deviceId":37,"longMacAddress":"5884e40000000439","shortMacAddress":259,"hoplist":"(259,3)","associationTime":"2019-06-10 22:43:54","lifeCheckInterval":5,"lastLiveCheck":"2019-06-11 07:11:37","onlineStatus":1,"txPowerValue":14,"deviceType":1,"frequencyBand":1,"lastLivecheck":"2019-06-11 07:11:36","disassociationState":0,"firmwareUpdateActivated":0,"firmwareUpdatePackagesSent":0,"firmwareUpdatePackagesUnsent":0,"firmwareUpdateInProgress":0,"deviceIdOem":"-1","deviceNameOem":"-1","deviceCompanyOem":"-1","binaryInputCount":0,"binaryOutputCount":0,"analogInputCount":0,"characterStringCount":1,"location":[{"location":"UK","locationWriteable":1,"changedAt":"2019-06-10 23:40:50"}],"description":[{"description":"DevKit","descriptionWriteable":1,"changedAt":"2019-06-10 23:40:54"}],"binaryInput":[],"binaryOutput":[],"analogInput":[],"characterString":[{"characterString":"149+0.0+99+26.5+0","characterStringWriteable":1,"changedAt":"2019-06-11 06:45:02"}]}
MY MAIN CODE:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace API_JSON_1
{
class Program
{
static void Main(string[] args)
{
var client = new WebClient();
var JSON = client.DownloadString("http://192.168.0.254:8000/nodes/longmac/5884e40000000439");
Console.WriteLine(JSON);
Console.WriteLine("----------------------------------------------");
CharacterString CSV = JsonConvert.DeserializeObject<CharacterString>(JSON);
Console.WriteLine("Sensor data: " + CSV.CharacterStringCharacterString);
}
}
}
MY CHARACTER STRING CLASS:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace API_JSON_1
{
public class CharacterStrings
{
public CharacterStrings CharString { get; set; }
}
public class CharacterString
{ public string CharacterStringCharacterString { get; set; }
public long CharacterStringWriteable { get; set; }
public DateTimeOffset ChangedAt { get; set; }
}
}
OUTPUT TO THE CONSOLE:
{"deviceId":37,"longMacAddress":"5884e40000000439","shortMacAddress":259,"hoplis
t":"(259,3)","associationTime":"2019-06-10 22:43:54","lifeCheckInterval":5,"last
LiveCheck":"2019-06-11 06:56:37","onlineStatus":1,"txPowerValue":14,"deviceType"
:1,"frequencyBand":1,"lastLivecheck":"2019-06-11 06:56:33","disassociationState"
:0,"firmwareUpdateActivated":0,"firmwareUpdatePackagesSent":0,"firmwareUpdatePac
kagesUnsent":0,"firmwareUpdateInProgress":0,"deviceIdOem":"-1","deviceNameOem":"
-1","deviceCompanyOem":"-1","binaryInputCount":0,"binaryOutputCount":0,"analogIn
putCount":0,"characterStringCount":1,"location":[{"location":"UK","locati
onWriteable":1,"changedAt":"2019-06-10 23:40:50"}],"description":[{"description"
:"DevKit","descriptionWriteable":1,"changedAt":"2019-06-10 23:40:54"}],"binaryIn
put":[],"binaryOutput":[],"analogInput":[],"characterString":[{"characterString"
:"149+0.0+99+26.5+0","characterStringWriteable":1,"changedAt":"2019-06-11 06:45:
02"}]}
----------------------------------------------
Sensor data:
Press any key to continue . . .
Obviously I was expecting/hoping that the penultimate line there would read:
"Sensor data: 149+0.0+99+26.5+0"
In order for this to work you have to modify your classes like this:
public class CharacterStrings
{
public List<CharacterStringObject> CharacterString { get; set; }
}
public class CharacterStringObject
{
public string CharacterString { get; set; }
public long CharacterStringWriteable { get; set; }
public DateTime ChangedAt { get; set; }
}
After that, after you read your JSON like that:
CharacterString CSV = JsonConvert.DeserializeObject<CharacterString>(JSON);
You end up with List<CharacterStringObject> with one element in it. So you take the first one like that and print it:
Console.WriteLine("Sensor data: " + CSV.CharacterString.First().CharacterString);
Cheers,
Edit: Tested it locally with your given JSON, works fine
Welcome to StackOverflow!
Something you need to keep in mind when converting a json string to an object (ie: Deserialize) is that the object to which you are converting the string into needs to match the format of the json string. In your case, the json string does not match the object to which you are converting.
Once you have the correct object, this will give you the output you want:
static void Main(string[] args)
{
string JSON = "{\"deviceId\":37,\"longMacAddress\":\"5884e40000000439\",\"shortMacAddress\":259,\"hoplist\":\"(259,3)\",\"associationTime\":\"2019-06-10 22:43:54\",\"lifeCheckInterval\":5,\"lastLiveCheck\":\"2019-06-11 07:11:37\",\"onlineStatus\":1,\"txPowerValue\":14,\"deviceType\":1,\"frequencyBand\":1,\"lastLivecheck\":\"2019-06-11 07:11:36\",\"disassociationState\":0,\"firmwareUpdateActivated\":0,\"firmwareUpdatePackagesSent\":0,\"firmwareUpdatePackagesUnsent\":0,\"firmwareUpdateInProgress\":0,\"deviceIdOem\":\"-1\",\"deviceNameOem\":\"-1\",\"deviceCompanyOem\":\"-1\",\"binaryInputCount\":0,\"binaryOutputCount\":0,\"analogInputCount\":0,\"characterStringCount\":1,\"location\":[{\"location\":\"UK\",\"locationWriteable\":1,\"changedAt\":\"2019-06-10 23:40:50\"}],\"description\":[{\"description\":\"DevKit\",\"descriptionWriteable\":1,\"changedAt\":\"2019-06-10 23:40:54\"}],\"binaryInput\":[],\"binaryOutput\":[],\"analogInput\":[],\"characterString\":[{\"characterString\":\"149+0.0+99+26.5+0\",\"characterStringWriteable\":1,\"changedAt\":\"2019-06-11 06:45:02\"}]}";
Console.WriteLine(JSON);
Console.WriteLine("----------------------------------------------");
RootObject CSV = JsonConvert.DeserializeObject<RootObject>(JSON);
// Option 1: Loop over the items in your List<CharacterString>...
foreach (var cs in CSV.characterString)
{
Console.WriteLine("Sensor data: " + cs.characterString);
}
// Option 2: Or, if you know there is only one in the list...
Console.WriteLine("Sensor data: " + CSV.characterString.First().characterString);
}
EDIT to explain the code above: Because characterString is a List<CharacterString>, it's technically possible that you could have more than one item in that list. Option 1: If you want, you can loop through that list to display the items in it. But if you know for certain that there will only be one item in the list, then, Option 2: You can just display the .First() item in the list.
I took the json sting you gave us, and using this handy website (http://json2csharp.com/#) I converted it into the following classes:
public class RootObject
{
public int deviceId { get; set; }
public string longMacAddress { get; set; }
public int shortMacAddress { get; set; }
public string hoplist { get; set; }
public string associationTime { get; set; }
public int lifeCheckInterval { get; set; }
public string lastLiveCheck { get; set; }
public int onlineStatus { get; set; }
public int txPowerValue { get; set; }
public int deviceType { get; set; }
public int frequencyBand { get; set; }
public string lastLivecheck { get; set; }
public int disassociationState { get; set; }
public int firmwareUpdateActivated { get; set; }
public int firmwareUpdatePackagesSent { get; set; }
public int firmwareUpdatePackagesUnsent { get; set; }
public int firmwareUpdateInProgress { get; set; }
public string deviceIdOem { get; set; }
public string deviceNameOem { get; set; }
public string deviceCompanyOem { get; set; }
public int binaryInputCount { get; set; }
public int binaryOutputCount { get; set; }
public int analogInputCount { get; set; }
public int characterStringCount { get; set; }
public List<Location> location { get; set; }
public List<Description> description { get; set; }
public List<object> binaryInput { get; set; }
public List<object> binaryOutput { get; set; }
public List<object> analogInput { get; set; }
public List<CharacterString> characterString { get; set; }
}
public class Location
{
public string location { get; set; }
public int locationWriteable { get; set; }
public string changedAt { get; set; }
}
public class Description
{
public string description { get; set; }
public int descriptionWriteable { get; set; }
public string changedAt { get; set; }
}
public class CharacterString
{
public string characterString { get; set; }
public int characterStringWriteable { get; set; }
public string changedAt { get; set; }
}
The CharacterString property in the json is an array of objects. Also the first property in those objects is characterString. Below is a working example
Output is Sensor Data: 149+0.0+99+26.5+0
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace SOTest
{
class Program
{
static void Main(string[] args)
{
var json =
"{\"deviceId\":37,\"longMacAddress\":\"5884e40000000439\",\"shortMacAddress\":259,\"hoplist\":\"(259,3)\",\"associationTime\":\"2019-06-10 22:43:54\",\"lifeCheckInterval\":5,\"lastLiveCheck\":\"2019-06-11 07:11:37\",\"onlineStatus\":1,\"txPowerValue\":14,\"deviceType\":1,\"frequencyBand\":1,\"lastLivecheck\":\"2019-06-11 07:11:36\",\"disassociationState\":0,\"firmwareUpdateActivated\":0,\"firmwareUpdatePackagesSent\":0,\"firmwareUpdatePackagesUnsent\":0,\"firmwareUpdateInProgress\":0,\"deviceIdOem\":\"-1\",\"deviceNameOem\":\"-1\",\"deviceCompanyOem\":\"-1\",\"binaryInputCount\":0,\"binaryOutputCount\":0,\"analogInputCount\":0,\"characterStringCount\":1,\"location\":[{\"location\":\"UK\",\"locationWriteable\":1,\"changedAt\":\"2019-06-10 23:40:50\"}],\"description\":[{\"description\":\"DevKit\",\"descriptionWriteable\":1,\"changedAt\":\"2019-06-10 23:40:54\"}],\"binaryInput\":[],\"binaryOutput\":[],\"analogInput\":[],\"characterString\":[{\"characterString\":\"149+0.0+99+26.5+0\",\"characterStringWriteable\":1,\"changedAt\":\"2019-06-11 06:45:02\"}]}";
var obj = JsonConvert.DeserializeObject<CharacterStrings>(json);
Console.WriteLine($"Sensor Data: {obj.CharacterString.First().CharacterString}");
Console.ReadKey();
}
public class CharacterStrings
{
public List<Characters> CharacterString { get; set; }
}
public class Characters
{ public string CharacterString { get; set; }
public long CharacterStringWriteable { get; set; }
public DateTime ChangedAt { get; set; }
}
}
}
You are defining the CSV object with CharacterSting. I should be CharacterStrings and Inside the CharacterStrings class it should to be array because your JSON is an array

Deserializing Server returned String to JSON

I am using the SharePoint REST API to do a search. I am pulling back the JSON results and reading them as follows:
HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create(querystring);
endpointRequest.Method = "GET";
endpointRequest.Accept = "application/json; odata=verbose";
endpointRequest.UseDefaultCredentials = true;
HttpWebResponse endpointResponse =(HttpWebResponse)endpointRequest.GetResponse();
Stream webStream = endpointResponse.GetResponseStream();
StreamReader responseReader = new StreamReader(webStream);
var results = responseReader.ReadToEnd();
This works fine, I can see the results in JSON format. So I created a class from the JSON in VS 2017 and here is the classes created from the JSON (this was done automatically with File=>Paste Special=>Paste JSON As Classes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class SharePointRESTResults
{
public class Rootobject
{
public D d { get; set; }
}
public class D
{
public Query query { get; set; }
}
public class Query
{
public __Metadata __metadata { get; set; }
public int ElapsedTime { get; set; }
public Primaryqueryresult PrimaryQueryResult { get; set; }
public Properties1 Properties { get; set; }
public Secondaryqueryresults SecondaryQueryResults { get; set; }
public string SpellingSuggestion { get; set; }
public Triggeredrules TriggeredRules { get; set; }
}
public class __Metadata
{
public string type { get; set; }
}
public class Primaryqueryresult
{
public __Metadata1 __metadata { get; set; }
public Customresults CustomResults { get; set; }
public string QueryId { get; set; }
public string QueryRuleId { get; set; }
public object RefinementResults { get; set; }
public Relevantresults RelevantResults { get; set; }
public object SpecialTermResults { get; set; }
}
public class __Metadata1
{
public string type { get; set; }
}
public class Customresults
{
public __Metadata2 __metadata { get; set; }
public object[] results { get; set; }
}
public class __Metadata2
{
public string type { get; set; }
}
public class Relevantresults
{
public __Metadata3 __metadata { get; set; }
public object GroupTemplateId { get; set; }
public object ItemTemplateId { get; set; }
public Properties Properties { get; set; }
public object ResultTitle { get; set; }
public object ResultTitleUrl { get; set; }
public int RowCount { get; set; }
public Table Table { get; set; }
public int TotalRows { get; set; }
public int TotalRowsIncludingDuplicates { get; set; }
}
public class __Metadata3
{
public string type { get; set; }
}
public class Properties
{
public Result[] results { get; set; }
}
public class Result
{
public __Metadata4 __metadata { get; set; }
public string Key { get; set; }
public string Value { get; set; }
public string ValueType { get; set; }
}
public class __Metadata4
{
public string type { get; set; }
}
public class Table
{
public __Metadata5 __metadata { get; set; }
public Rows Rows { get; set; }
}
public class __Metadata5
{
public string type { get; set; }
}
public class Rows
{
public Result1[] results { get; set; }
}
public class Result1
{
public __Metadata6 __metadata { get; set; }
public Cells Cells { get; set; }
}
public class __Metadata6
{
public string type { get; set; }
}
public class Cells
{
public Result2[] results { get; set; }
}
public class Result2
{
public __Metadata7 __metadata { get; set; }
public string Key { get; set; }
public object Value { get; set; }
public string ValueType { get; set; }
}
public class __Metadata7
{
public string type { get; set; }
}
public class Properties1
{
public Result3[] results { get; set; }
}
public class Result3
{
public __Metadata8 __metadata { get; set; }
public string Key { get; set; }
public string Value { get; set; }
public string ValueType { get; set; }
}
public class __Metadata8
{
public string type { get; set; }
}
public class Secondaryqueryresults
{
public __Metadata9 __metadata { get; set; }
public object[] results { get; set; }
}
public class __Metadata9
{
public string type { get; set; }
}
public class Triggeredrules
{
public __Metadata10 __metadata { get; set; }
public object[] results { get; set; }
}
public class __Metadata10
{
public string type { get; set; }
}
}
}
So I now am trying to deserialize the results as follows:
SharePointRESTResults resultX = JsonConvert.DeserializeObject<SharePointRESTResults>(results());
The results I need should be in the Result2 Class. The problem I have is that this line is setting resultX = to "ConsoleApplication1.SharePointRESTResults" and nothing more. I looked in the JSON Serializing and Deserializing here: JSON Documentation but still cannot get the results into the class so I can pull out the data. I appreciate any help.
The main points are -
The Account Declaration.
JsonProperty attribute.
NOTE : If you have an object Which keys can change, Then you need to use a
Dictionary<string, T>
. A regular class won't work for that; neither will a
List<T>
.

How will I get this json into my c# class

I would like to read in a json respons to my c# class for learning and having problem with it.
This is the main code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using Newtonsoft.Json;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var webClient = new System.Net.WebClient();
var json = webClient.DownloadString("https://api.trafiklab.se/samtrafiken/resrobotstops/GetDepartures.json?key=[KEY]&apiVersion=2.2&locationId=7420752&coordSys=RT90");
This url will return this json
{"getdeparturesresult":{"departuresegment":[{"departure":{"location":
{"#id":"7420752","#x":"1271307","#y":"6404493","name":"Göteborg Brunnsparken"}
,"datetime":"2014-12-10 12:27"},"direction":"Göteborg Kålltorp","segmentid":
{"mot":{"#displaytype":"S","#type":"SLT","#text":"Spårvagn"},"carrier":
{"name":"Västtrafik","url":"http:\/\/www.vasttrafik.se\/","id":"279","number":"3"}}},
The first problem is that when generating a c# class it will complain about the # in the variable name. How can this be fixed? I mean I cant change the json respons. That is what I get. My guess would be this:
getdeparturesresult.departuresegment.departure.location["#x"]);
The second is how will I write to get it in to my class? What should be used?
I have tried this but then it will complain about my RootObject:
string json = r.ReadToEnd();
List<RootObject> items = JsonConvert.DeserializeObject<List<RootObject>>(json);
Lets say I got a class like this
public class Location
{
public string id { get; set; }
public string x { get; set; }
public string y { get; set; }
public string name { get; set; }
}
public class Departure
{
public Location location { get; set; }
public string datetime { get; set; }
}
public class Mot
{
public string displaytype { get; set; }
public string type { get; set; }
public string text { get; set; }
}
public class Carrier
{
public string name { get; set; }
public string url { get; set; }
public string id { get; set; }
public string number { get; set; }
}
public class Segmentid
{
public Mot mot { get; set; }
public Carrier carrier { get; set; }
}
public class Departuresegment
{
public Departure departure { get; set; }
public string direction { get; set; }
public Segmentid segmentid { get; set; }
}
public class Getdeparturesresult
{
public Departuresegment departuresegment { get; set; }
}
public class RootObject
{
public Getdeparturesresult getdeparturesresult { get; set; }
}
I have also tried this
dynamic array = JsonConvert.DeserializeObject(json);
foreach (var item in array)
{
Console.WriteLine("{0}", item);
}
This will printout whats in the json. But how do I get it to be read into my class? I cant figure it out. It must be simple but I cant get it right.
You only need to change like:
public class Getdeparturesresult
{
public IEnumerable<Departuresegment> departuresegment { get; set; }
}
You can still use the Json.net serializer (JsonConvert).
Edit:
To handle the "#id" property you can do this:
[JsonProperty("#id")]
public string id { get; set; }
You could accomplish that with JavaScriptSerializer.
var root = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(json);
It worked for me, but I had to change the type of Getdeparturesresult.departuresegment property to an array:
public class Getdeparturesresult
{
public Departuresegment[] departuresegment { get; set; }
}
Update:
To deserialize JSON properties with special characters with .NET, you can use DataContractJsonSerializer.
RootObject root;
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
root = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(RootObject)).ReadObject(stream) as RootObject;
But your code will have to get verbose. You need to mark every class with [DataContract] and every property with [DataMember] attributes. For the properties whose names are not equal to those of the source, use [DataMember(Name = "#fancy_name")].
[DataContract]
public class Location
{
[DataMember(Name = "#id")]
public string id { get; set; }
[DataMember(Name = "#x")]
public string x { get; set; }
[DataMember(Name = "#y")]
public string y { get; set; }
[DataMember]
public string name { get; set; }
}
// etc.

C# JSON Object wont deserialize

So I have been able to get JSON objects for a few things, however this object is quite a bit more complex.
I'm trying to get comments from Reddit.
Here is the method I use:
public async Task<List<string>> GetComments(string currentSubreddit, string topicID)
{
string commentUrl = "http://www.reddit.com/r/" + currentSubreddit + "/comments/" + topicID + "/.json";
List<Comments> commentList = new List<Comments>();
string jsonText = await wc.GetJsonText(commentUrl);
Comments.RootObject deserializeObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Comments.RootObject>(jsonText);
List<string> commentListTest = new List<string>();
//List<string> commentListTest = deserializeObject.data.children[0].data.children;
return commentListTest;
}
This is the GetJsonText method:
public async Task<string> GetJsonText(string url)
{
var request = WebRequest.Create(url);
string text;
request.ContentType = "application/json; charset=utf-8";
var response = (HttpWebResponse)await request.GetResponseAsync();
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
return text;
}
And here is a link to the Object: http://pastebin.com/WQ8XXGNA
And a link to the jsonText: http://pastebin.com/7Kh6cA9a
The error returned says this:
An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in mscorlib.dll but was not handled in user code
Additional information: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'JuicyReddit.Comments+RootObject' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
I'd appreciate if anybody could help me with figuring out whats wrong with this.
Thanks
There are a few problems with your code actually
public async Task<List<string>> GetComments(string currentSubreddit, string topicID)
You don't need to return a list of string here, u need to return a full object
First rename RootObject in the model to an appropriate name such as "CommentsObject"
So set up your class like so and name it CommentsObject.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace YOURNAMESPACE.Comments
{
public class MediaEmbed
{
}
public class SecureMediaEmbed
{
}
public class Data4
{
public int count { get; set; }
public string parent_id { get; set; }
public List<string> children { get; set; }
public string name { get; set; }
public string id { get; set; }
public string subreddit_id { get; set; }
public object banned_by { get; set; }
public string subreddit { get; set; }
public object likes { get; set; }
public object replies { get; set; }
public bool? saved { get; set; }
public int? gilded { get; set; }
public string author { get; set; }
public object approved_by { get; set; }
public string body { get; set; }
public object edited { get; set; }
public object author_flair_css_class { get; set; }
public int? downs { get; set; }
public string body_html { get; set; }
public string link_id { get; set; }
public bool? score_hidden { get; set; }
public double? created { get; set; }
public object author_flair_text { get; set; }
public double? created_utc { get; set; }
public object distinguished { get; set; }
public object num_reports { get; set; }
public int? ups { get; set; }
}
public class Child2
{
public string kind { get; set; }
public Data4 data { get; set; }
}
public class Data3
{
public string modhash { get; set; }
public List<Child2> children { get; set; }
public object after { get; set; }
public object before { get; set; }
}
public class Replies
{
public string kind { get; set; }
public Data3 data { get; set; }
}
public class Data2
{
public string domain { get; set; }
public object banned_by { get; set; }
public MediaEmbed media_embed { get; set; }
public string subreddit { get; set; }
public object selftext_html { get; set; }
public string selftext { get; set; }
public object likes { get; set; }
public object secure_media { get; set; }
public object link_flair_text { get; set; }
public string id { get; set; }
public SecureMediaEmbed secure_media_embed { get; set; }
public bool clicked { get; set; }
public bool stickied { get; set; }
public string author { get; set; }
public object media { get; set; }
public int score { get; set; }
public object approved_by { get; set; }
public bool over_18 { get; set; }
public bool hidden { get; set; }
public string thumbnail { get; set; }
public string subreddit_id { get; set; }
public object edited { get; set; }
public object link_flair_css_class { get; set; }
public object author_flair_css_class { get; set; }
public int downs { get; set; }
public bool saved { get; set; }
public bool is_self { get; set; }
public string permalink { get; set; }
public string name { get; set; }
public double created { get; set; }
public string url { get; set; }
public object author_flair_text { get; set; }
public string title { get; set; }
public double created_utc { get; set; }
public int ups { get; set; }
public int num_comments { get; set; }
public bool visited { get; set; }
public object num_reports { get; set; }
public object distinguished { get; set; }
public Replies replies { get; set; }
public int? gilded { get; set; }
public string parent_id { get; set; }
public string body { get; set; }
public string body_html { get; set; }
public string link_id { get; set; }
public bool? score_hidden { get; set; }
public int? count { get; set; }
public List<string> children { get; set; }
}
public class Child
{
public string kind { get; set; }
public Data2 data { get; set; }
}
public class Data
{
public string modhash { get; set; }
public List<Child> children { get; set; }
public object after { get; set; }
public object before { get; set; }
}
public class CommentsObject
{
public string kind { get; set; }
public Data data { get; set; }
}
}
Make your namespace correct!
Then handle the request and deserialise into a list of commentobjects: (u can use the webclient instead of httpclient if you want, this is just an example)
private HttpClient client;
public async Task<List<CommentsObject>> GetComments()
{
client = new HttpClient();
var response = await client.GetAsync("http://www.reddit.com/r/AskReddit/comments/1ut6xc.json");
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync();
List<CommentsObject> comments = await JsonConvert.DeserializeObjectAsync<List<CommentsObject>>(json);
return comments;
}
else
{
throw new Exception("Errorhandling message");
}
}
It's not ideal (and not completely an answer but more of a work around) but I created models that mock the reddit response json to make deserialization super easy. I use JsonProperty attributes on my model properties to pretty up the models a bit.
Here are the models
And since my models directly mock the json I can just use json.net's generic deserialize method.

Categories