How can I get specific values from JObject in c# [duplicate] - c#

This question already has answers here:
How can I deserialize JSON with C#?
(19 answers)
Closed 4 years ago.
I need to retrieve specific values from API response. My response looks like one below. How can I access to [productCodeScheme] value of each pack?
dynamic api = JObject.Parse(response.Content);
// api contains
{
"operationCode": "12200000",
"packs": [
{
"pack": {
"productCodeScheme": "ppn",
"productCode": "15000436574634",
"serialNumber": "0000000001",
"batchId": "00001",
"expiryDate": "201201"
},
"result": {
"operationCode": "61020008",
"warning": "The product code is invalid."
}
},
{
"pack": {
"productCodeScheme": "gs1",
"productCode": "15000436574634",
"serialNumber": "0000000002",
"batchId": "00001",
"expiryDate": "201201"
},
"result": {
"operationCode": "11310300",
"information": "The pack has been marked as stolen.",
"state": "Stolen"
}
}
]
}

If you want your object to stay dynamic, you could just do
dynamic result = JsonConvert.DeserializeObject<dynamic>(response.Content);
after, you can access the objects inside like below:
foreach(dynamic item in result.packs)
{
string productCodeScheme = item.pack.productCodeScheme.ToString();
}
However, i would strongly suggest that you to deserialize your JSON responses into defined objects instead of using dynamic. dynamics are both insecure and inefficient. You can do someting like example below,
public class PackDetails
{
public string productCodeScheme { get; set; }
public string productCode { get; set; }
public string serialNumber { get; set; }
public string batchId { get; set; }
public string expiryDate { get; set; }
}
public class Result
{
public string operationCode { get; set; }
public string warning { get; set; }
public string information { get; set; }
public string state { get; set; }
}
public class Pack
{
public PackDetails pack { get; set; }
public Result result { get; set; }
}
public class ResponseObject
{
public string operationCode { get; set; }
public List<Pack> packs { get; set; }
}
then you can deserialize a ResponseObject like below and use it
var responseObject = JsonConvert.DeserializeObject<ResponseObject>();
foreach(PackDetails item in responseObject.packs)
{
string productCodeScheme = item.pack.productCodeScheme;
}

Related

Deserialize JSON using specific properties

I'm trying to deserialize JSON without declaring every property in C#. Here is a cut-down extract of the JSON:
{
"resourceType": "export",
"type": "search",
"total": 50,
"timestamp": "2020-08-02T18:26:06.747+00:00",
"entry": [
{
"url": "test.com/123",
"resource": {
"resourceType": "Slot",
"id": [
"123"
],
"schedule": {
"reference": {
"value": "testvalue"
}
},
"status": "free",
"start": "2020-08-03T08:30+01:00",
"end": "2020-08-03T09:00+01:00"
}
}
]
}
I want to get the values out of entry → resource, id and start.
Any suggestions on the best way to do this?
I've made very good experiences with json2sharp. You can enter your JSON data there and it will generate the classes you need to deserialize the JSON data for you.
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
public class Root
{
public string resourceType { get; set; }
public string type { get; set; }
public int total { get; set; }
public DateTime timestamp { get; set; }
public List<Entry> entry { get; set; }
}
The next step is to choose a framework which will help you to deserialize. Something like Newtonsoft JSON.
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
If you want to get the data without declaring classes, you can use Json.Net's LINQ-to-JSON API (JToken, JObject, etc.). You can use the SelectToken method with a JsonPath expression to get what you are looking for in a couple of lines. Note that .. is the recursive descent operator.
JObject obj = JObject.Parse(json);
List<string> ids = obj.SelectToken("..resource.id").ToObject<List<string>>();
DateTimeOffset start = obj.SelectToken("..resource.start").ToObject<DateTimeOffset>();
Working demo here: https://dotnetfiddle.net/jhBzl4
If it turns out there are actually multiple entries and you want to get the id and start values for all of them, you can use a query like this:
JObject obj = JObject.Parse(json);
var items = obj["entry"]
.Children<JObject>()
.Select(o => new
{
ids = o.SelectToken("resource.id").ToObject<List<string>>(),
start = o.SelectToken("resource.start").ToObject<DateTimeOffset>()
})
.ToList();
Demo: https://dotnetfiddle.net/Qe8NB7
I am not sure why you don't deserialize the lot (even if it's minimally populated) since you have to do the inner classes anyway.
Here is how you could bypass some of the classes (1) by digging into the JObjects
Given
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
You could call
var results = JObject.Parse(input)["entry"]
.Select(x => x.ToObject<Entry>());

JSON with array structure [duplicate]

This question already has answers here:
How can I deserialize JSON with C#?
(19 answers)
How to auto-generate a C# class file from a JSON string [closed]
(3 answers)
Closed 2 years ago.
I just wanna ask if how to implement in c# a json data with array structure. This is the sample data below:
{
"contact":
{
"contact_type_ids": ["CUSTOMER"],
"name":"JSON Sample ResellerAVP",
"main_address":
{
"address_type_id":"ACCOUNTS",
"address_line_1":"Ayala Hills",
"city":"Muntinlupa",
"region":"NCR",
"postal_code":"1770",
"country_group_id":"ALL"
}
}
}
JSON overview:
{ } - Object
[ ] - Array
"a": something - Property
A property can have an object, array, or value type as its value. For example:
{
"a": true,
"b": "hello",
"c": 5.2,
"d": 1,
"e": { "eChildProperty": "test" },
"f": [ "a", "b", "c" ]
}
Let's start transcribing this JSON into classes!
{
"contact":
{
"contact_type_ids": ["CUSTOMER"],
"name":"JSON Sample ResellerAVP",
"main_address":
{
"address_type_id":"ACCOUNTS",
"address_line_1":"Ayala Hills",
"city":"Muntinlupa",
"region":"NCR",
"postal_code":"1770",
"country_group_id":"ALL"
}
}
}
OK, so we have a root object with a property "contact", which is also an object. Let's represent both of those:
public class RootObject
{
public Contact Contact { get; set; }
}
public class Contact
{
}
Now we need to add Contact's properties. It has 3: contact_type_ids is an array of strings, name is a string, and main address is a complex object. Let's represent those:
public class Contact
{
[JsonProperty("contact_type_ids")]
public IList<string> ContactTypeIds { get; set; } // I'm using an IList, but any collection type or interface should work
public string Name { get; set; }
[JsonProperty("main_address")]
public Address MainAddress { get; set; }
}
public class Address
{
}
Finally we need to work on the Address object:
public class Address
{
[JsonProperty("address_type_id")]
public string AddressTypeId { get; set; }
[JsonProperty("address_line_1")]
public string AddressLine1 { get; set; }
public string City { get; set; }
public string Region { get; set; }
[JsonProperty("postal_code")]
public string PostalCode { get; set; }
[JsonProperty("country_group_id")]
public string CountryGroupId { get; set; }
}
Putting this all together we get:
public class RootObject
{
public Contact Contact { get; set; }
}
public class Contact
{
[JsonProperty("contact_type_ids")]
public IList<string> ContactTypeIds { get; set; } // I'm using an IList, but any collection type or interface should work
public string Name { get; set; }
[JsonProperty("main_address")]
public Address MainAddress { get; set; }
}
public class Address
{
[JsonProperty("address_type_id")]
public string AddressTypeId { get; set; }
[JsonProperty("address_line_1")]
public string AddressLine1 { get; set; }
public string City { get; set; }
public string Region { get; set; }
[JsonProperty("postal_code")]
public string PostalCode { get; set; }
[JsonProperty("country_group_id")]
public string CountryGroupId { get; set; }
}
And we can use it like so:
RootObject deserialized = JsonConvert.DeserializeObject<RootObject>(jsonString);
Try it online
JSON isn't complicated by any stretch of the imagination. It's really simple to understand and manually convert into classes just by looking at the data you have.

Cannot deserialize the JSON array (e.g. [1,2,3]) into type ' ' because type requires JSON object (e.g. {“name”:“value”})

I have JSON returning in the following format:
{
"Items": [
{
"unique_id": "11111111111",
"rages": {
"rage_content": "Hello rage 2",
"date_stamp": "21/07/2017",
"id": 2
}
},
{
"unique_id": "2222222222",
"rages": {
"rage_content": "Hello rage 1",
"date_stamp": "21/07/2017",
"id": 1
}
}
],
"Count": 2,
"ScannedCount": 2
}
And I have the following 2 classes defined:
Items.cs:
namespace ragevent_A0._0._1
{
class Items
{
public String rage_id { get; set; }
public rage rage { get; set; }
}
}
rage.cs:
class rage
{
public String rage_content { get; set; }
public String date_stamp { get; set; }
public int id { get; set; }
}
I am using the following code in order to attempt to deseralize the JSON returned above:
List<Items> data = JsonConvert.DeserializeObject<List<Items>>(json);
However, I am not able to successfully deserialize the data due to the above error. I have tried a few solutions online, however I have not managed to find a solution which works with the format of my returned JSON. I have used a JSON formatter and it is formatted correctly, so that shouldn't be the issue.
Any help would be much appreciated!
For the posted JSON data below should be the model you need (credit: http://json2csharp.com/). There is mismatch between the property name rage_id. You can use JsonProperty attribute
public class Rages
{
public string rage_content { get; set; }
public string date_stamp { get; set; }
public int id { get; set; }
}
public class Item
{
[JsonProperty(Name="rage_id")]
public string unique_id { get; set; }
public Rages rages { get; set; }
}
public class RootObject
{
public List<Item> Items { get; set; }
public int Count { get; set; }
public int ScannedCount { get; set; }
}
Your deserialization should be
var data = JsonConvert.DeserializeObject<RootObject>(json);

Json.Net deserialize JSON objects with index as name [duplicate]

This question already has answers here:
How can I parse a JSON string that would cause illegal C# identifiers?
(3 answers)
Closed 8 years ago.
I am attempting to parse JSON from a web service using Json.NET, the web service returns data in the following format:
{
"0": {
"ID": 193,
"Title": "Title 193",
"Description": "Description 193",
"Order": 5,
"Hyperlink": "http://someurl.com"
},
"1": {
"ID": 228,
"Title": "Title 228",
"Description": "Description 228",
"Order": 4,
"Hyperlink": "http://someurl.com"
},
"2": {
"ID": 234,
"Title": "Title 234",
"Description": "Description 234",
"Order": 3,
"Hyperlink": "http://someurl.com"
}
}
I used json2sharp to generate a class from the JSON:
public class __invalid_type__0
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class __invalid_type__1
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class __invalid_type__2
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class RootObject
{
public __invalid_type__0 __invalid_name__0 { get; set; }
public __invalid_type__1 __invalid_name__1 { get; set; }
public __invalid_type__2 __invalid_name__2 { get; set; }
}
I then cleaned up the class and was left with the following:
public class Articles
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class FeaturedArticles
{
public List<Articles> articles { get; set; }
}
When I attempt to load the data into my singleton for use in the app:
private void fetchFeaturedArticles()
{
var client = new RestClient (_featuredArticlesJsonUrl);
var request = new RestRequest (Method.GET);
var response = client.Execute (request);
_featuredArticles = JsonConvert.DeserializeObject<FeaturedArticles> (response.Content);
foreach (Articles a in _featuredArticles.Articles)
Console.WriteLine (a.Title);
}
I find that the Articles do not get deserialized.
I've verified that the JSON data is returned from the web service. I believe the issue exists in the structure of my JSON feed, where each item returned from the feed is given a name which equals the index the item is being returned as.
I am new to using Json.NET so I'm not sure how I should proceed; I cannot change the structure of the JSON feed but need to consume it's data. Anyone have any recommendations?
You don't need FeaturedArticles class, you can deserialize the JSON into a Dictionary<string, Articles> like this:
private void fetchFeaturedArticles()
{
var client = new RestClient (_featuredArticlesJsonUrl);
var request = new RestRequest (Method.GET);
var response = client.Execute (request);
Dictionary<string, Articles> _featuredArticles = JsonConvert.DeserializeObject<Dictionary<string, Articles>>(response.Content);
foreach (string key in _featuredArticles.Keys)
{
Console.WriteLine(_featuredArticles[key].Title);
}
}
Demo: https://dotnetfiddle.net/ZE1BMl

Deserialize JSON with Json.NET in Windows 8 Store App (C#)

i'm trying to program a Windows Runtime Component in C# in Visual Studio 2012 for Windows 8.
I have some issues by using Json.NET to deserialize a JSON like this:
{
"header": {
"id": 0,
"code": 0,
"hits": 10
},
"body": {
"datalist": [
{
"name": "",
"city": "",
"age": 0
},
{
"name": "",
"city": "",
"age": 0
},
{
"name": "",
"city": "",
"age": 0
}
]
}
}
My intention is to get a top-level Dictionary out of this and to interpret every value as a string. For this example you would get a dictionary with two keys (header and body) and the matching values as strings. After this you could go down the tree.
A function like this
Dictionary<string, string> jsonDict =
JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
would be nice, but this one only accept string-values.
Do anybody knows how to ignore the types or get it on another way?
Furthermore to get out of the body-value "{"datalist": [ { "name": "", ....}]}" a list of dictionaries.
Thanks in advance!
I would use this site and deserialize as
var myObj =JsonConvert.DeserializeObject<RootObject>(json);
public class Header
{
public int id { get; set; }
public int code { get; set; }
public int hits { get; set; }
}
public class Datalist
{
public string name { get; set; }
public string city { get; set; }
public int age { get; set; }
}
public class Body
{
public List<Datalist> datalist { get; set; }
}
public class RootObject
{
public Header header { get; set; }
public Body body { get; set; }
}
You can also use dynamic keyword without declaring any classes
dynamic myObj =JsonConvert.DeserializeObject(json);
var age = myObj.body.datalist[1].age;
And since JObject implements IDictionary<> this is also possible
var jsonDict = JObject.Parse(json);
var age = jsonDict["body"]["datalist"][1]["age"];
If you're having a problem defining your classes, a nice feature in VS 2012 allows you to generate classes to hold your JSON/XML data using the Paste Special command under Edit. For instance, your JSON created this class:
public class Rootobject
{
public Header header { get; set; }
public Body body { get; set; }
}
public class Header
{
public int id { get; set; }
public int code { get; set; }
public int hits { get; set; }
}
public class Body
{
public Datalist[] datalist { get; set; }
}
public class Datalist
{
public string name { get; set; }
public string city { get; set; }
public int age { get; set; }
}
...which you could then deserialize your request into the type of RootObject, e.g.
var obj = JsonConvert.DeserializeObject<RootObject>(json);

Categories

Resources