Deserialise JSon of Nested HTML Elements using C# - c#

I've used this useful JQuery function that serializes nested elements. the problem is how to deserialise it using c#.
the following code gives
No parameterless constructor defined for type of 'System.Collections.Generic.IList`
string json = #"{""root"":{""id"":""main"",""text"":""150px"",""children"":
[{""id"":""divcls"",""text"":""50px"",""children"":
[{""id"":""qs1"",""text"":""0px"",""children"":[]}]},
{""id"":""divcls2"",""text"":""50px"",""children"":[]},
{""id"":""divcls3"",""text"":""50px"",""children"":[]}]}}";
IList<Commn.main1> objs = new JavaScriptSerializer()
.Deserialize<IList<Commn.main1>>(json);
string blky = "";
foreach (var item in objs)
{
blky += item.id;
}
Label1.Text = Convert.ToString(blky);
public class main1
{
public string id { get; set; }
public string text { get; set; }
public sub1 children { get; set; }
}
public class sub1
{
public string Qid { get; set; }
public string Qval { get; set; }
}
My Json is only 2 Levels deeep If the solution is recursive how could i know the depth of the element
By the way can a class reference itself like this
public class main1
{
public string id { get; set; }
public string text { get; set; }
public main1 children { get; set; }
}

First of all, yes a class can reference itself. In your case, you would need to have a main1[] property to represent its children.
public class main1
{
public string id { get; set; }
public string text { get; set; }
public main1[] children { get; set; }
}
Next, your json string contains not only a main1 object, but also some other object with a "root" property of type main1. It's perfectly fine, but then you need another class to deserialize into :
public class foo
{
public main1 root { get; set; }
}
You should then be able to use the Deserialize method to get an instance of foo :
var myFoo = new JavaScriptSerializer().Deserialize<foo>(json);

Related

Convert Rest API JSON Response into C# object

I have a code REST API response which is json, and parsing to JObject and pulling a value from it. But i am getting the error when parsing to JObject.
Error: "Unexpected character encountered while parsing value: S. Path '', line 0, position 0."
Is there any other way to convert Json string to C# object.
I have the following code:
using Newtonsoft.Json;
using (HttpResponseMessage message = httpclient.GetAsync(folderIdURL).Result)
{
if(message.IsSuccessStatusCode)
{
var dataobjects = message.Content.ReadAsStringAsync();
//dataobjects = "{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/","title":"DQL query results","author":[{"name":"EMC Documentum"}],"updated":"2019-05-02T15:19:52.508+00:00","page":1,"items-per-page":100,"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)"}],"entries":[{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)&index=0","title":"0b0111738011c114","updated":"2019-05-02T15:19:52.508+00:00","published":"2019-05-02T15:19:52.508+00:00","links":[{"rel":"edit","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c114"}],"content":{"json-root":"query-result","definition":"https://gbc-dev5.cloud.wc.com/DctmRest/repositori es/dmgbsap_crt/types/dm_sysobject","properties":{"r_object_id":"0b0111738011c114","object_name":"04"},"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c114"}]}},{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)&index=1","title":"0b0111738011c115","updated":"2019-05-02T15:19:52.509+00:00","published":"2019-05-02T15:19:52.509+00:00","links":[{"rel":"edit","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c115"}],"content":{"json-root":"query-result","definition":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/types/dm_sysobject","properties":{"r_object_id":"0b0111738011c115","object_name":"05"},"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c115"}]}}]}"
JObject responseObj = JObject.Parse(dataobjects.ToString());
String id = (String)responseObj["entries" -->"content"-->"properties"-->"object_name"];
}
}
}
I am expecting the value from (String)responseObject["enteries"]["content"][" properties"]["object_name"]
JObjects are a pain. You could get a sample of the JSON response and paste it into a converter like json2csharp.com. It will generate a class for you which you can then use like so:
Generated Class:
public class MyClass
{
public string SomeProperty { get; set; }
public string AnotherProperty { get; set; }
}
Usage:
if (message.IsSuccessStatusCode)
{
var deserializedObject = JsonConvert.DeserializeObject<MyClass>(response.Content.ReadAsStringAsync().Result);
Console.WriteLine(deserializedObject.SomeProperty);
}
I would suggest to follow those steps:
You need to check that your json is actually a json, because an error says it is not. You can use online tools like this
If possible, avoid JObject and generate real classes. It is not that hard if you know the structure, and you can use another online tools
Modify your code to use classes
so you will have something like:
using System;
using Newtonsoft.Json;
namespace ConsoleApp11
{
class Program
{
public class Message
{
public Enteries enteries { get; set; }
}
public class Enteries
{
public Content content { get; set; }
}
public class Content
{
public Properties properties { get; set; }
}
public class Properties
{
public string object_name { get; set; }
}
static void Main(string[] args)
{
var input = "{\"enteries\":{\"content\":{ \"properties\":{ \"object_name\":\"your value string\"}}}}";
Message msg = JsonConvert.DeserializeObject<Message>(input);
Console.WriteLine(msg?.enteries?.content?.properties?.object_name ?? "no value");
Console.ReadKey();
}
}
}
I hope it helps 😊
Thank you so much for all the help and trips. Finally i am able to get the required value from JSON string.
Here is the Final code json2csharp.com
public class Author
{
public string name { get; set; }
}
public class Link
{
public string rel { get; set; }
public string href { get; set; }
}
public class Link2
{
public string rel { get; set; }
public string href { get; set; }
}
public class Properties
{
public string r_object_id { get; set; }
public string object_name { get; set; }
}
public class Link3
{
public string rel { get; set; }
public string href { get; set; }
}
public class Content
{
public string json_root { get; set; }
public string definition { get; set; }
public Properties properties { get; set; }
public List<Link3> links { get; set; }
}
public class Entry
{
public string id { get; set; }
public string title { get; set; }
public DateTime updated { get; set; }
public DateTime published { get; set; }
public List<Link2> links { get; set; }
public Content content { get; set; }
}
public class RootObject
{
public string id { get; set; }
public string title { get; set; }
public List<Author> author { get; set; }
public DateTime updated { get; set; }
public int page { get; set; }
public int items_per_page { get; set; }
public List<Link> links { get; set; }
public List<Entry> entries { get; set; }
}
Using Newtonsoft.Json
First get the list of entries from the responseObj. Then loop each entries and use LINQ to JSON to get values by property name or index.
You can use Item[Object] index on JObject/JArray and then cast the returned JValue to the type you want
JObject responseObj = JObject.Parse(dataobjects.ToString());
// get JSON result objects into a list
IList<JToken> entries = responseObj ["entries"].Children().ToList();
foreach(JToken entry in entries)
{
string object_name = (string) entry["content"]["properties"]["object_name"];
}

Unable to deserialize JSON in c#

I am getting the below JSON in response from a REST API.
{
"data":{
"id":123,
"zoneid":"mydomain.com",
"parent_id":null,
"name":"jaz",
"content":"172.1 6.15.235",
"ttl":60,
"priority":null,
"type":"A",
"regions":[
"global"
],
"system_record":false,
"created_at":"2017-09-28T12:12:17Z",
"updated_at":"2017-09-28T12:12:17Z"
}
}
and trying to resolve using below code but that doesn't result in a correctly deserialized type.
var model = JsonConvert.DeserializeObject<ResponseModel>(response);
below is a class according the field I received in JSON response.
public class ResponseModel
{
public int id { get; set; }
public string zone_id { get; set; }
public int parent_id { get; set; }
public string name { get; set; }
public string content { get; set; }
public int ttl { get; set; }
public int priority { get; set; }
public string type { get; set; }
public string[] regions { get; set; }
public bool system_record { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
}
What is missing?
You're missing a wrapper class.
public class Wrapper
{
public ResponseModel data {get;set}
}
and then do:
var model = JsonConvert.DeserializeObject<Wrapper>(response).data;
to get the instance of your ResponseModel out the data property.
You can deduct this from your json:
{ "data":
{ "id":123, /*rest omitted */ }
}
The type that will receive this JSON needs to have a property named data. The suggested Wrapper class acts as that type.
According to json2csharp website, your model seems to be incorrect. Try this one :
public class ResponseModel
{
public int id { get; set; }
public string zoneid { get; set; }
public object parent_id { get; set; }
public string name { get; set; }
public string content { get; set; }
public int ttl { get; set; }
public object priority { get; set; }
public string type { get; set; }
public List<string> regions { get; set; }
public bool system_record { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
}
public class RootObject
{
public ResponseModel data { get; set; }
}
Here a cool trick you can do in Visual Studio 2015-2017 where it generates the the correct class if you just copy the JSON (ctrl + c).
You need to create a new class in visual studio and once inside the class go to Edit menu -> Paste special -> paste JSON As Classes.
Steps to generate json class
This will generate the C# object for that json for you and save you all the hassle :)
Your model does not match your response - it matches the data property. Simply wrap another object round it
public class ResponseData
{
public ResponseModel Data {get; set; {
}
and then
var model = JsonConvert.DeserializeObject<ResponseData>(response);

Parse certain data using JSON.Net

I'm trying to parse a certain link from some JSON data I'm getting but I can't seem to do it? Here's some sample data (from PayPal API):
{"id":"PAY-3YA6562986829024GK2JH7UQ","intent":"sale","state":"created","payer":{"payment_method":"paypal"},"transactions":[{"amount":{"total":"12.00","currency":"USD"},"description":"creating a payment","related_resources":[]}],"create_time":"2016-01-10T15:59:14Z","links":[{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-3YA6562986829024GK2JH7UQ","rel":"self","method":"GET"},{"href":"https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-5CP140577W0453458","rel":"approval_url","method":"REDIRECT"},{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-3YA6562986829024GK2JH7UQ/execute","rel":"execute","method":"POST"}]}
So I've tried to do the following:
dynamic stuff = JsonConvert.DeserializeObject(createdPayment.ConvertToJson());
string paymentURL = stuff.href;
MessageBox.Show(paymentURL);
And I've also tried to use Newtonsoft.Json.Linqand populate stuff.links into a JAraay and then pull the link via an index, with no luck. This method that I'm using doesn't give me an error, it just returns a blank string for me?
Any ideas?
The problem is that your "href" links are within your "links" property, you can access them like this:
dynamic stuff = JsonConvert.DeserializeObject(json);
foreach (var item in stuff.links)
{
MessageBox.Show(item.href);
}
EDIT: added example of getting a list of links
dynamic stuff = JsonConvert.DeserializeObject(json);
var links = new List<string>();
foreach (var item in stuff.links)
{
links.Add((string)item.href);
}
You should create a class which hold the values you want from the JSON string.
The class will look something like this:
public class Payer
{
public string payment_method { get; set; }
}
public class Amount
{
public string total { get; set; }
public string currency { get; set; }
}
public class Transaction
{
public Amount amount { get; set; }
public string description { get; set; }
public List<object> related_resources { get; set; }
}
public class Link
{
public string href { get; set; }
public string rel { get; set; }
public string method { get; set; }
}
public class RootObject
{
public string id { get; set; }
public string intent { get; set; }
public string state { get; set; }
public Payer payer { get; set; }
public List<Transaction> transactions { get; set; }
public string create_time { get; set; }
public List<Link> links { get; set; }
}
Then you will be able to do something like this (using Newtonsoft):
var object = JsonConvert.DeserializeObject<RootObject>(jsonstring);
You will then be able to iterate over the List<Link> links object and get the href value from there.
If you need parse data then you can simply try this example console app. And read more at Newtonsoft api reference.
class Program
{
class HrefResult
{
public string Href { get; set; }
public string Rel { get; set; }
public string Method { get; set; }
}
static void Main(string[] args)
{
String createdPayment = #"{""id"":""PAY - 3YA6562986829024GK2JH7UQ"",""intent"":""sale"",""state"":""created"",""payer"":{""payment_method"":""paypal""},""transactions"":[{""amount"":{""total"":""12.00"",""currency"":""USD""},""description"":""creating a payment"",""related_resources"":[]}],""create_time"":""2016 - 01 - 10T15: 59:14Z"",""links"":[{""href"":""https://api.sandbox.paypal.com/v1/payments/payment/PAY-3YA6562986829024GK2JH7UQ"",""rel"":""self"",""method"":""GET""},{""href"":""https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-5CP140577W0453458"",""rel"":""approval_url"",""method"":""REDIRECT""},{""href"":""https://api.sandbox.paypal.com/v1/payments/payment/PAY-3YA6562986829024GK2JH7UQ/execute"",""rel"":""execute"",""method"":""POST""}]}";
JObject stuff = JObject.Parse(createdPayment);
IList<Newtonsoft.Json.Linq.JToken> results = stuff["links"].Children().ToList();
IList<HrefResult> hrefResults = new List<HrefResult>();
foreach (JToken result in results)
{
HrefResult hrefResult = Newtonsoft.Json.JsonConvert.DeserializeObject<HrefResult>(result.ToString());
hrefResults.Add(hrefResult);
}
foreach(var elem in hrefResults) Console.WriteLine("{0}", elem.Href);
}
}

Json not mapping properly in C#

Here is a json document that I wanted to map it to C# poco classes. I wrote some classes but they didn't work. I got null in my result object. Any ideas?
I used Newtonsoft's json converter.
{
"retrieval-response":{
"cdata":{
"identifier":"777400",
"document-count":"62"
},
"index":"10",
"count":"25"
}
}
C# map classes;
public class result
{
[JsonProperty("retrieval-response")]
public aResult res { get; set; }
public int index { get; set; }
public int count { get; set; }
}
public class aResult
{
public cdata data { get; set; }
}
public class cdata
{
[JsonProperty("identifier")]
public string identif { get; set; }
[JsonProperty("document-count")]
public string count { get; set; }
}
You model is wrong. Try this:
public class Wrapper
{
[JsonProperty("retrieval-response")]
public Result Result { get; set; }
}
public class Result
{
[JsonProperty("cdata")]
public Data Data { get; set; }
public int Index { get; set; }
public int Count { get; set; }
}
public class Data
{
[JsonProperty("identifier")]
public string Identifier { get; set; }
[JsonProperty("document-count")]
public string Count { get; set; }
}
Then you can deserialize it with the following line:
var myResult = JsonConvert.DeserializeObject<Wrapper>(json);
Please note that I've also wrote your property and class names in pascal case. These are the naming conventions from Microsoft.

Deserializing JSON using C# and custom classes

I've got an application that is receiving a JSON response. I've been trying to get it to deserialize, so I can more easily use the data in the application, but after going through several other articles on how to get this to work, I haven't had any success. The List is always empty at the end of the deserialize. The test JSON data is below, and below that is my current code.
{"vehicles":{"size":10,"next":10,"vehicle":[{"vin":"5GZCZ33Z47S000016","make":"Saturn","model":"Saturn Vue","year":2007,"manufacturer":"GM","phone":5002022424,"unitType":"EMBEDDED","primaryDriverId":450984739,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/5GZCZ33Z47S000016","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984739"},{"vin":"1G6DA67VX80000014","make":"Cadillac","model":"STS AWD","year":2008,"manufacturer":"GM","phone":7039277239,"unitType":"EMBEDDED","primaryDriverId":450984752,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1G6DA67VX80000014","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984752"},{"vin":"1GNFC26069R000015","make":"Cadillac","model":"Suburban (4X2) 4 door","year":2009,"manufacturer":"GM","phone":2815079899,"unitType":"EMBEDDED","primaryDriverId":450984738,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1GNFC26069R000015","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984738"},{"vin":"1GKUKEEF9AR000010","make":"GMC","model":"Denali","year":2010,"manufacturer":"General Motors","phone":3132200010,"unitType":"EMBEDDED","primaryDriverId":548392002,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1GKUKEEF9AR000010","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/548392002"},{"vin":"5TFHW5F15AX000013","make":"Toyota","model":"Tundra 4WD Truck","year":2010,"manufacturer":"Toyota","phone":3372413717,"unitType":"FMV","primaryDriverId":450984766,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/5TFHW5F15AX000013","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984766"},{"vin":"1G1PJ5S95B7000009","make":"Chevrolet","model":"Cruze","year":2011,"manufacturer":"General Motors","phone":8035553074,"unitType":"EMBEDDED","primaryDriverId":548392002,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1G1PJ5S95B7000009","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/548392002"},{"vin":"2CNALPEC3B6000001","make":"Chevrolet","model":"Equinox","year":2011,"manufacturer":"General Motors","phone":3135450001,"unitType":"EMBEDDED","primaryDriverId":450984732,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/2CNALPEC3B6000001","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984732"},{"vin":"1GCRCSE09BZ000005","make":"Chevrolet","model":"Silverado Crew Cab","year":2011,"manufacturer":"General Motors","phone":8035553074,"unitType":"EMBEDDED","primaryDriverId":450984732,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1GCRCSE09BZ000005","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984732"},{"vin":"1G1RD6E47BU000008","make":"Chevrolet","model":"Volt","year":2011,"manufacturer":"General Motors","phone":3139030008,"unitType":"EMBEDDED","primaryDriverId":548392002,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1G1RD6E47BU000008","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/548392002"},{"vin":"1G6DH5E53C0000003","make":"Cadillac","model":"CTS Coupe","year":2012,"manufacturer":"General Motors","phone":3136440003,"unitType":"EMBEDDED","primaryDriverId":450438292,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1G6DH5E53C0000003","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450438292"}]}}
This is the function from the Main Form that is handling passing the info into objects.
void Deserialize(IRestResponse response)
{
string workingString = response.Content;
var list = new JavaScriptSerializer().Deserialize<List<GMVehicles>>(workingString);
}
These are the classes that the deserialzer should be putting the data
public class GMVehicles
{
public Vehicle vehicle { get; set; }
}
public class Vehicle
{
public string vin { get; set; }
public string make { get; set; }
public string model { get; set; }
public string year { get; set; }
public string manufacturer { get; set; }
public string phone { get; set; }
public string unitType { get; set; }
public string primaryDriverId { get; set; }
public string url { get; set; }
public string primaryDriverUrl { get; set; }
}
What am I doing wrong?
Your Vehicle class is fine. Now you need a wrapper around your GMVehicles class:
public class Root
{
public GMVehicles Vehicles { get; set; }
}
also your GMVehicles is wrong, it should contain a collection (because the vehicle property in your JSON is a list, not an object):
public class GMVehicles
{
public Vehicle[] Vehicle { get; set; }
}
Alright, now you deserialize the root:
void Deserialize(IRestResponse response)
{
string workingString = response.Content;
var root = new JavaScriptSerializer().Deserialize<Root>(workingString);
Vehicle[] list = root.Vehicles.Vehicle;
// ... do something with the list of vehicles here
}

Categories