Parse JSON using c# - c#

I have been using NewtonSoft JSON Convert library to parse and convert JSON string to C# objects. I am unable to convert it into C# object because I cant make a C# class out of this JSON string.
Here is the JSON string:
{
"appId":"G9RNVJYTS6SFY",
"merchants":{
"RZX9YMHSMP6A8":[
{
"objectId":"A:G9RNVJYTS6SFY",
"type":"DELETE",
"ts":1522736100111
}
],
"MNOVJT2ZRRRSC":[
{
"objectId":"A:G9RNVJYTS6SFY",
"type":"CREATE",
"ts":1522736100111
}
]
},
... and so on
}
The names RZX9YMHSMP6A8 and MNOVJT2ZRRRSC change from request to request
USED
var dict = JsonConvert.DeserializeObject<Dictionary<string, RootObject>>(JSON);
I got exception while this line is executed
Error converting value "G9RNVJYTS6SFY" to type 'RootObject'. Path 'appId', line 1, position 24.
public class Merchant
{
public string objectId
{
get;
set;
}
public string type
{
get;
set;
}
public long ts
{
get;
set;
}
}
public class Merchants
{
public List<Merchant> merchant
{
get;
set;
}
}
public class RootObject
{
public string appId
{
get;
set;
}
public Merchants merchants
{
get;
set;
}
}

You can convert this json to c# class structure using a Dictionary to hold the merchants (where the ID is the string key):
public class RootObject
{
public string AppId { get; set; }
public Dictionary<string, List<ChildObject>> Merchants { get; set; }
}
public class ChildObject
{
public string ObjectId { get; set; }
public string Type { get; set; }
public long Ts { get; set; }
}
You can then loop over the childobjects like so:
foreach (var kvp in rootObject.Merchants)
{
var childObjects = kvp.Value;
foreach (var childObject in childObjects) {
Console.WriteLine($"MerchantId: {kvp.Key}, ObjectId: {childObject.ObjectId}, Type: {childObject.Type}");
}
}

Related

Convert complex JSON to C# Model and downloading Data

I'm trying to convert a data from a nested JSon file to C# Model, and I get this error :
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[convert_json_to_model.Fields]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'nhits', line 1, position 9.
Here is some data
{
"nhits":17933,
"parameters":{
"dataset":[
"osm-fr-bars#babel"
],
"rows":3,
"start":0,
"format":"json",
"timezone":"UTC"
},
"records":[
{
"datasetid":"osm-fr-bars#babel",
"recordid":"d95394fd7d34aa34aa9b236661bce9cda534a8ab",
"fields":{
"other_tags":"{\"cuisine\": \"tapas\", \"ref:FR:CRTA\": \"RESAQU047V506W6V\",
\"capacity\": \"14\", \"description\": \"Tous les jours \u00e0 partir de 7h\",
\"source\": \"BDOrtho IGN; Cadastre M\u00e0J 2015; Sirtaqui\", \"outdoor_seating\":
\"yes\", \"source:ref:FR:CRTA\": \"Sirtaqui\"}",
"name":"Au boin coin",
"geo_point_2d":[
44.0549704,
0.2603921
],
"phone":"+33 5 53 65 67 45"
},
"geometry":{
"type":"Point",
"coordinates":[
0.2603921,
44.0549704
]
}
Here is the link of my Json file to see all fields :
https://data.opendatasoft.com/api/records/1.0/search/?dataset=osm-fr-bars%40babel&rows=30
Here is my model after using the tool JSON to C#
public class Fields
{
[JsonProperty("other_tags")]
public string OtherTags { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("geo_point_2d")]
public List<double> GeoPoint2d { get; set; }
[JsonProperty("phone")]
public string Phone { get; set; }
}
public class Geometry
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("coordinates")]
public List<double> Coordinates { get; set; }
}
public class Record
{
[JsonProperty("datasetid")]
public string Datasetid { get; set; }
[JsonProperty("recordid")]
public string Recordid { get; set; }
[JsonProperty("fields")]
public Fields Fields { get; set; }
[JsonProperty("geometry")]
public Geometry Geometry { get; set; }
}
public class Root
{
[JsonProperty("records")]
public List<Record> Records { get; set; }
}
Here is the method to deserialize
static async Task Main(string[] args)
{
string url = "https://data.opendatasoft.com/api/records/1.0/search/?dataset=osm-fr-bars%40babel&rows=30";
HttpClient httpClient = new HttpClient();
try
{
var httpResponseMessage = await httpClient.GetAsync(url);
string jsonResponse = await httpResponseMessage.Content.ReadAsStringAsync();
List<Fields> myBars = JsonConvert.DeserializeObject<List<Fields>>(jsonResponse);
foreach (var bar in myBars)
{
Console.WriteLine($"{bar.Name}");
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
In the main, the HTTP response is deserialized to the type List<Fields>. But the JSON rather corresponds the type Root. Try :
//List<Fields> myBars = JsonConvert.DeserializeObject<List<Fields>>(jsonResponse);
Root myBars = JsonConvert.DeserializeObject<Root>(jsonResponse);
Please organise your model well.
Fields myBars = JsonConvert.DeserializeObject<Fields>(jsonResponse);
or
Root myBars = JsonConvert.DeserializeObject<Root>(jsonResponse);
public class Root
{
[JsonProperty("records")]
public List<Record> Records { get; set; }
}
public class Record
{
[JsonProperty("datasetid")]
public string Datasetid { get; set; }
[JsonProperty("recordid")]
public string Recordid { get; set; }
[JsonProperty("fields")]
public Fields Fields { get; set; }
[JsonProperty("geometry")]
public Geometry Geometry { get; set; }
}
public class Fields
{
[JsonProperty("other_tags")]
public string OtherTags { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("geo_point_2d")]
public List<double> GeoPoint2d { get; set; }
[JsonProperty("phone")]
public string Phone { get; set; }
}
public class Geometry
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("coordinates")]
public List<double> Coordinates { get; set; }
}
fix your class Root and add a missed Parameters class
Root data =JsonConvert.DeserializeObject<Root>(jsonResponse);
List<Fields> myBars = data.Records.Select(f=> f.Fields).ToList();
foreach (var bar in myBars)
{
Console.WriteLine($"{bar.Name}");
}
public partial class Root
{
[JsonProperty("nhits")]
public long Nhits { get; set; }
[JsonProperty("parameters")]
public Parameters Parameters { get; set; }
[JsonProperty("records")]
public List<Record> Records { get; set; }
}
public partial class Parameters
{
[JsonProperty("dataset")]
public List<string> Dataset { get; set; }
[JsonProperty("rows")]
public long Rows { get; set; }
[JsonProperty("start")]
public long Start { get; set; }
[JsonProperty("format")]
public string Format { get; set; }
[JsonProperty("timezone")]
public string Timezone { get; set; }
}
Problem solved, i changed the loop from foreach to for with index, and i should have added this parameters :
for (int i=0;i<myBars.Records.Count();i++)
{
Console.WriteLine($"{myBars.Records[i].Fields.Name}");
}

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"];
}

Parse json string to find and element

I have following json:
{
"578080":{
"success":true,
"data":{
"price_overview":{
"currency":"USD",
"initial":1799,
"final":1799,
"discount_percent":0
}
}
}
}
I want to search "initial".
How can I do this using Json.Net or any other efficient means in C#?
Note : i haven't tried anything because i am unsure where to start
Since this is a Dictionary<string,object> you can follow this, Deserialize a Dictionary
public class PriceOverview
{
public string currency { get; set; }
public int initial { get; set; }
public int final { get; set; }
public int discount_percent { get; set; }
}
public class Data
{
public PriceOverview price_overview { get; set; }
}
public class RootObject
{
public bool success { get; set; }
public Data data { get; set; }
}
var results = JsonConvert.DeserializeObject<Dictionary<string, RootObject>>(json);
foreach (var result in results)
{
Console.WriteLine(result.Key);
Console.WriteLine(result.Value.data.price_overview.currency);
Console.WriteLine(result.Value.data.price_overview.initial);
Console.WriteLine(result.Value.data.price_overview.final);
Console.WriteLine(result.Value.data.price_overview.discount_percent);
}
Output
578080
USD
1799
1799
0
Full demo here

Deserialise a Kraken JSON in C#

I used to be loading data from Cryptocompare's API.
This post got me what I wanted for Cryptocompare.
Parsing Cryptocompare API Json data in C#
However, I notice that this API is not bulletproof, it's not always returning an answer. So I want to use Kraken itself.
Now I am trying to deserialise the new JSON but this is not straightforward as Cryptocompare's JSON.
Here is an example JSON:
https://api.kraken.com/0/public/OHLC?pair=ETHUSD&interval=30
{"error":[],"result":{"XETHZUSD":[[1519236000,"825.94","846.00","825.94","845.00","835.62","858.29381033",708],[1519237800,"846.00","848.84","835.55","836.00","844.31","647.42747317",731],[1519239600,"836.00","841.09","830.76","834.89","835.13","1051.44905097",609],[1520530200,"706.24","710.43","701.90","704.59","707.70","1763.41692283",459]],"last":1520528400}}
I have not been able to deserialise this JSON.
Solved!!!
final solution:
var Results_Exchange_Kraken = JsonConvert.DeserializeObject<DataRoot_Kraken>(Content_Exchange_Kraken);
var price_data_kraken = Results_Exchange_Kraken.result.XETHZUSD;
public class Kraken_Result
{
public List<List<object>> XETHZUSD { get; set; }
public int last { get; set; }
}
public class DataRoot_Kraken
{
public List<object> error { get; set; }
public Kraken_Result result { get; set; }
}
Thank you! I'll bookmark the URL.
Use this Model to de-serialise your data
public class Result
{
public List<List<object>> XETHZUSD { get; set; }
public int last { get; set; }
}
public class RootObject
{
public List<object> error { get; set; }
public Result result { get; set; }
}
Model Generated by Model Generator
Then use NewtonSoft for c# to de-serialise your data
E.g.
RootObject tmp = JsonConvert.DeserializeObject<RootObject>("JSON String here");
final solution:
var Results_Exchange_Kraken = JsonConvert.DeserializeObject<DataRoot_Kraken>(Content_Exchange_Kraken);
var price_data_kraken = Results_Exchange_Kraken.result.XETHZUSD;
public class Kraken_Result
{
public List<List<object>> XETHZUSD { get; set; }
public int last { get; set; }
}
public class DataRoot_Kraken
{
public List<object> error { get; set; }
public Kraken_Result result { get; set; }
}

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);
}
}

Categories