I have the below response from the API in a console application written in C#:
{
"d": {
"results": [
{
"__metadata": {
"id": "123",
"uri": "456",
"type": "789"
},
"PERNR": "1",
"USRID": "2"
},
{
"__metadata": {
"id": "159",
"uri": "951",
"type": "753"
},
"PERNR": "4",
"USRID": "6"
}
]
}
}
And used the below code to deserialize:
public class d
{
public results results { get; set; }
}
public class results
{
public string PERNR { get; set; }
public string USRID { get; set; }
public __metadata __metadata { get; set; }
}
public class __metadata
{
public string id { get; set;}
public string uri { get; set; }
public string type { get; set; }
}
var serilizer = new JavaScriptSerializer();
d output = serilizer.Deserialize<d>(response.Content);
But the result is null. Is there any problem in the definition of the classes?
The properties should start with a capital letter, to match the case of the properties in the JSON response. Change the class definitions as follows:
public class D
{
public Results[] results { get; set; }
}
public class Results
{
public string PERNR { get; set; }
public string USRID { get; set; }
public Metadata __metadata { get; set; }
}
public class Metadata
{
public string id { get; set;}
public string uri { get; set; }
public string type { get; set; }
}
Change deserialize line to:
var serilizer = new JavaScriptSerializer();
D output = serilizer.Deserialize<D>(response.Content);
The issue is results is an array in your json, where in your class, it is an object. Change it to
public class d
{
public Result[] results { get; set; }
}
If you use a JSON to C# converter like json2csharp or Visual Studio's Paste JSON As Classes you'll get :
public class Root
{
public D d { get; set; }
}
public class D
{
public List<Result> results { get; set; }
}
public class Metadata
{
public string id { get; set; }
public string uri { get; set; }
public string type { get; set; }
}
public class Result
{
public Metadata __metadata { get; set; }
public string PERNR { get; set; }
public string USRID { get; set; }
}
There are two important differences :
The JSON document contains a root element with an attribute named d, not a D object
D.results is a collection of Result objects, not a single object
Related
I noticed that I would get different results when deserializing objects different ways. I must have missed something but couldn't figure out what.
Here is the json:
{
"content_version": "1",
"date_created": "2020-10-06T13:52:15.288Z",
"date_updated": "2020-10-06T13:54:24.325Z",
"content": {
"EN": {
"name_full": {
"text": "Test"
},
"name_short": {
"text": "TEST"
}
}
},
"tools": {
"car": true,
"truck": true,
"fleet": {
"use": true,
"languages": [
{
"fileName": "file1.json",
"name": {
"text": "English"
}
}
]
}
}
}
The following are the classes that I generated using a tool:
public class Root
{
public string content_version { get; set; }
public DateTime date_created { get; set; }
public DateTime date_updated { get; set; }
public ContentRootObject content { get; set; }
public Tools tools { get; set; }
}
public class ContentRootObject
{
[JsonProperty(PropertyName = "content")]
public Dictionary<string, ContentItem> DataItems { get; set; }
}
public class ContentItem
{
public NameFull name_full { get; set; }
public NameShort name_short { get; set; }
}
public class Tools
{
public bool car { get; set; }
public bool truck { get; set; }
public Fleet fleet { get; set; }
}
public class NameFull
{
public string text { get; set; }
}
public class NameShort
{
public string text { get; set; }
}
public class EN
{
public NameFull name_full { get; set; }
public NameShort name_short { get; set; }
}
public class Name
{
public string text { get; set; }
}
public class Language
{
public string fileName { get; set; }
public Name name { get; set; }
}
public class Fleet
{
public bool use { get; set; }
public List<Language> languages { get; set; }
}
and here is the code that I tried for deserializing :
var objTool = Newtonsoft.Json.JsonConvert.DeserializeObject<Tools>(json);
var objRoot = Newtonsoft.Json.JsonConvert.DeserializeObject<Root>(json);
var objContent = Newtonsoft.Json.JsonConvert.DeserializeObject<ContentRootObject>(json)
and here is what I got for each of the objects:
objTool: 'fleet' was returned as null in 'tools'
objRoot: the DataItems of 'content' was null.
objContent: got an error saying "Unexpected character encountered while parsing value: {. Path 'content.EN', line 1, position 146."
Although I can just deserialize the whole thing, I only need objTool and objContent and I was wondering what I did wrong in the above code? Thanks!
The issue is that the class that you have as a wrapper for the dictionary is not represented in the JSON. It'll deserialize the dictionary if you change the root object to this:
public class Root
{
public string content_version { get; set; }
public DateTime date_created { get; set; }
public DateTime date_updated { get; set; }
public Dictionary<string, ContentItem> content { get; set; }
public Tools tools { get; set; }
}
[
{
"data": {
"user": {
"id": "12345678",
"displayName": "name",
"subscriptionProducts": [
{
"id": "123456",
"emoteSetID": "123456",
"name": "name",
"__typename": "SubscriptionProduct"
},
{
"id": "123456",
"emoteSetID": "123456",
"name": "name2000",
"__typename": "SubscriptionProduct"
},
{
"id": "123456",
"emoteSetID": "123456",
"name": "name_3000",
"__typename": "SubscriptionProduct"
}
],
"self": null,
"__typename": "User"
},
"currentUser": null,
"requestInfo": {
"countryCode": "US",
"__typename": "RequestInfo"
}
},
"extensions": {
"durationMilliseconds": 31,
"operationName": "ChannelPage_SubscribeButton_User",
"requestID": "1234124124asd123412425151245124"
}
}
]
I get this response in my C# application and I am trying to just grab the "ID" which is 12345678
after {"data":{"user":{"id":"12345678"... blah blah blah
I wrote a code but it does not work
string value = httpreqResp.Split(new[] { "/"id/": /"" }, StringSplitOptions.None)[1].Split('"')[0];
Can someone help if possible
You go to http://QuickType.io and paste your json in
You set some other options like the name of the root class
It generates you a bunch of C# - I would have done this with your json but I'm on a cellphone and QTIO doesn't work on a cell; can't paste the json in, so I had to use the example temperatures.json
The generated C# looks like this, a host of classes that represent the objects in the JSON then some handy one shot methods for converting from/to the JSON:
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var temperatures = Temperatures.FromJson(jsonString);
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class Temperatures
{
[JsonProperty("description")]
public Description Description { get; set; }
[JsonProperty("data")]
public Dictionary<string, Datum> Data { get; set; }
}
public partial class Datum
{
[JsonProperty("value")]
public string Value { get; set; }
[JsonProperty("anomaly")]
public string Anomaly { get; set; }
}
public partial class Description
{
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("units")]
public string Units { get; set; }
[JsonProperty("base_period")]
public string BasePeriod { get; set; }
}
public partial class Temperatures
{
public static Temperatures FromJson(string json) => JsonConvert.DeserializeObject<Temperatures>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this Temperatures self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}
you get your response string str from the server
you write a line of code like var parsed = YourRootClassName.FromJson(str)
and then your desired data is available in e.g parsed[0].Data.User.Id
You can do a similar thing with a visual studio's "Paste Json as classes" function, except it doesn't write the handy deserializer bits for you like QuickType does. Those parts don't change though, so if QTIO ever went away, this answer could still stand by blending the deser methods above with the resulting c# from doing a paste as classes
If you really want to do it using string split, just split on " and it'll be the seventh element of the resulting array. Maybe. It'll be fragile as hell, which is why you should parse it
Edit: json2charp can be used from a cell, their version looks like this:
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class SubscriptionProduct {
public string id { get; set; }
public string emoteSetID { get; set; }
public string name { get; set; }
public string __typename { get; set; }
}
public class User {
public string id { get; set; }
public string displayName { get; set; }
public List<SubscriptionProduct> subscriptionProducts { get; set; }
public object self { get; set; }
public string __typename { get; set; }
}
public class RequestInfo {
public string countryCode { get; set; }
public string __typename { get; set; }
}
public class Data {
public User user { get; set; }
public object currentUser { get; set; }
public RequestInfo requestInfo { get; set; }
}
public class Extensions {
public int durationMilliseconds { get; set; }
public string operationName { get; set; }
public string requestID { get; set; }
}
public class MyArray {
public Data data { get; set; }
public Extensions extensions { get; set; }
}
public class Root {
public List<MyArray> MyArray { get; set; }
}
And would be used like:
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(responseStringFromWebservice);
var id = myDeserializedClass.MyArray[0].Data.User.id;
This is a JSON string,
You can JsonSerializer.Deserialize to convert it to a C# class.
First create your own classes to store data,like this
public class SubscriptionProduct {
public string id { get; set; }
public string emoteSetID { get; set; }
public string name { get; set; }
public string __typename { get; set; }
}
public class User {
public string id { get; set; }
public string displayName { get; set; }
public List<SubscriptionProduct> subscriptionProducts { get; set; }
public object self { get; set; }
public string __typename { get; set; }
}
public class RequestInfo {
public string countryCode { get; set; }
public string __typename { get; set; }
}
public class Data {
public User user { get; set; }
public object currentUser { get; set; }
public RequestInfo requestInfo { get; set; }
}
public class Extensions {
public int durationMilliseconds { get; set; }
public string operationName { get; set; }
public string requestID { get; set; }
}
public class MyArray {
public Data data { get; set; }
public Extensions extensions { get; set; }
}
public class MyClass {
public List<MyArray> MyArray { get; set; }
}
Then use this:
var mydata = JsonSerializer.Deserialize<MyClass>(jsonString);
I'm deserializing a JSON object into a class that I created using json2csharp. Once deserialized, I cannot access the nested values of this object. The error I get is this:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
This is the class I created;
public class Ticker
{
public List<object> error { get; set; }
public Result result { get; set; }
public class Result
{
public XXBTZCAD XBTCAD { get; set; }
public class XXBTZCAD
{
public List<string> a { get; set; }
public List<string> b { get; set; }
public List<string> c { get; set; }
public List<string> v { get; set; }
public List<string> p { get; set; }
public List<int> t { get; set; }
public List<string> l { get; set; }
public List<string> h { get; set; }
public string o { get; set; }
}
}
}
Here is the JSON string, at the time of this writing:
{
"error": [
],
"result": {
"XXBTZCAD": {
"a": [
"4776.10000",
"8",
"8.000"
],
"b": [
"4773.90000",
"1",
"1.000"
],
"c": [
"4776.20000",
"0.02510294"
],
"v": [
"4.85183508",
"61.15237421"
],
"p": [
"4775.02293",
"4767.92898"
],
"t": [
126,
608
],
"l": [
"4756.70000",
"4720.60000"
],
"h": [
"4780.00000",
"4783.30000"
],
"o": "4776.40000"
}
}
}
This is the code that deserializes and attempts to display the first value of List a
private async void GetKraken(object sender, RoutedEventArgs e)
{
var client = new RestClient();
IRestResponse response;
Ticker BTCCADTicker = new Ticker();
client.BaseUrl = new Uri("https://api.kraken.com/0/public/Ticker?pair=XBTCAD");
var request = new RestRequest();
response = await client.ExecuteTaskAsync(request);
BTCCADTicker = JsonConvert.DeserializeObject<Ticker>(response.Content);
MessageBox.Show(BTCCADTicker.result.XBTCAD.a[0]);
}
I would expect to see a value around 4700 to be returned, but I'm getting the error above instead. What gives? Any help is appreciated.
You haven't defined XXBTZCAD in your model. You've called it XBTCAD by mistake. Fixed it looks like this:
public class Ticker
{
public List<object> error { get; set; }
public Result result { get; set; }
public class Result
{
public XXBTZCAD XXBTZCAD { get; set; }
public class XXBTZCAD
{
public List<string> a { get; set; }
public List<string> b { get; set; }
public List<string> c { get; set; }
public List<string> v { get; set; }
public List<string> p { get; set; }
public List<int> t { get; set; }
public List<string> l { get; set; }
public List<string> h { get; set; }
public string o { get; set; }
}
}
}
I see now that this is the same name as the nested class. I'd recommend the simple solution of not nesting your classes:
public class Ticker
{
public List<object> error { get; set; }
public Result result { get; set; }
}
public class Result
{
public XXBTZCAD XXBTZCAD { get; set; }
}
public class XXBTZCAD
{
public List<string> a { get; set; }
public List<string> b { get; set; }
public List<string> c { get; set; }
public List<string> v { get; set; }
public List<string> p { get; set; }
public List<int> t { get; set; }
public List<string> l { get; set; }
public List<string> h { get; set; }
public string o { get; set; }
}
If you really want to nest them, simply rename class XXBTZCAD to something else. It's the property name that's important for deserialization, not the type name.
I suggest copy your JSON and in Visual Studio :
Edit > Paste Special > Parse JSON As Classes
public class Ticker
{
public object[] error { get; set; }
public Result result { get; set; }
}
public class Result
{
public XXBTZCAD XXBTZCAD { get; set; }
}
public class XXBTZCAD
{
public string[] a { get; set; }
public string[] b { get; set; }
public string[] c { get; set; }
public string[] v { get; set; }
public string[] p { get; set; }
public int[] t { get; set; }
public string[] l { get; set; }
public string[] h { get; set; }
public string o { get; set; }
}
and you can use this method to get the result :
public static async Task<string> GetKraken()
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("https://api.kraken.com/0/public/Ticker?pair=XBTCAD");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
}
and then use the method and convert it to get actual object:
var ticker = JsonConvert.DeserializeObject<Ticker>(GetKraken().Result);
I need to query for and get the matched JSON string. Following is my JSON:
I need to query the JSON I receive in the HTTP RESPONSE, match the JSON where code=2, then extract the text=Jenny kisworth
JSON
[
{
"code":1234,
"parentCode":9898,
"language":{
"lookup": "IN",
"code": 1
},
"parentType": "Patient",
"text": "James Berth"
},
{
"code":4567,
"parentCode":8989,
"language":{
"lookup": "IN",
"code": 1
},
"parentType": "Patient",
"text": "James Bond"
},
{
"code":89101,
"parentCode":2525,
"language":{
"lookup": "OUT",
"code": 2
},
"parentType": "Patient",
"text": "Jenny kisworth"
}
]
CODE:
public class JSonData
{
[Newtonsoft.Json.JsonProperty("code")]
public string code { get; set; }
[Newtonsoft.Json.JsonProperty("language")]
public List<Datum> language { get; set; }
}
public class Datum
{
public string lookup { get; set; }
public int code { get; set; }
}
//only posting code relevant to the subject
HttpResponseMessage responseCode = client.GetAsync(codeParameters).Result;
if (responseCode.IsSuccessStatusCode)
{
var dataObjects = responseAlternateTitles.Content.ReadAsStringAsync();
dataObjects.Wait();
string dataObjectsString = dataObjects.Result.ToString();
var data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<JSonData>>(dataObjectsString);
}
In the above I get an error: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List1[BCMTest.Datum]' because the type requires a JSON array`
Your classes should look more like this, how do i know? http://json2csharp.com/
public class Language
{
public string lookup { get; set; }
public int code { get; set; }
}
public class JSonData
{
public int code { get; set; }
public int parentCode { get; set; }
public Language language { get; set; }
public string parentType { get; set; }
public string text { get; set; }
}
...
var data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<JSonData>>(dataObjectsString);
You are getting an error because your JSON doesnot have a object of array in language as you are expecting in your class object.
Change the JSonData class -> language
public class JSonData
{
[Newtonsoft.Json.JsonProperty("code")]
public string code { get; set; }
[Newtonsoft.Json.JsonProperty("language")]
public Datum language { get; set; }
}
public class Language
{
public string lookup { get; set; }
public int code { get; set; }
}
public class JSonData
{
[Newtonsoft.Json.JsonProperty("code")]
public string code { get; set; }
[Newtonsoft.Json.JsonProperty("parentCode")]
public int parentCode { get; set; }
[Newtonsoft.Json.JsonProperty("language")]
public Language language { get; set; }
[Newtonsoft.Json.JsonProperty("parentType")]
public string parentType { get; set; }
[Newtonsoft.Json.JsonProperty("text")]
public string text { get; set; }
}
var data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<JSonData>>(dataObjectsString);
var filtereddata = data.Where(s => s.language.code.Equals(2));
I have a collection of classes set out like this:
public class Xml
{
public string version { get; set; }
public string encoding { get; set; }
}
public class Content
{
public string Expires { get; set; }
public string MaxArrivalScope { get; set; }
}
public class Trip
{
public string ETA { get; set; }
public string TripNo { get; set; }
public string WheelchairAccess { get; set; }
}
public class Destination
{
public string Name { get; set; }
public List<Trip> Trip { get; set; }
}
public class Route
{
public string RouteNo { get; set; }
public string Name { get; set; }
public Destination Destination { get; set; }
}
public class Platform
{
public string PlatformTag { get; set; }
public string Name { get; set; }
public Route Route { get; set; }
}
public class JPRoutePositionET
{
public string xmlns { get; set; }
public string xsi { get; set; }
public string schemaLocation { get; set; }
public Content Content { get; set; }
public Platform Platform { get; set; }
}
public class RootObject
{
public Xml xml { get; set; }
public JPRoutePositionET JPRoutePositionET { get; set; }
}
}
I have JSON like this:
{
"xml": {
"version": "1.0",
"encoding": "utf-8"
},
"JPRoutePositionET": {
"xmlns": "urn:connexionz-co-nz:jp",
"xsi": "http://www.w3.org/2001/XMLSchema-instance",
"schemaLocation": "urn:connexionz-co-nz:jp JourneyPlanner.xsd",
"Content": {
"Expires": "2017-04-09T15:59:31+12:00",
"MaxArrivalScope": "60"
},
"Platform": {
"PlatformTag": "2628",
"Name": "Awatea Rd near Awatea Gdns",
"Route": {
"RouteNo": "125",
"Name": "Redwood/Westlake",
"Destination": {
"Name": "Westlake & Halswell",
"Trip": [
{
"ETA": "4",
"TripNo": "4751",
"WheelchairAccess": "true"
},
{
"ETA": "32",
"TripNo": "4752",
"WheelchairAccess": "true"
}
]
}
}
}
}
}
Why is Newtonsoft not parsing correctly to the Platform class? It returns null. Will I need to format the JSON to cut out all the other information I don't want? Or is it something I am missing?
Fabio's Comment of
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsonString);
Worked.
But now when I get JSON like pastebin.com/pebp178s I can't seem to use Json2CSharp to get the classes I'd need as it doesn't make Destination a List, it also changes Trip to an Object instead of a class. Which is really weird. It just throws an error saying the JSON can't be parsed.