In my c# project, I would like to access specific information (POI name and distance) inside a complex and nested JSON.
This JSON is the result of an Azure Maps API call.
I have tried to deserialise it into an object. But this JSON is too complex and I am unable to do it.
What is the best way to extract the information I need ?
{
"summary": {
"query": "university",
"queryType": "NON_NEAR",
"queryTime": 103,
"numResults": 1,
"offset": 0,
"totalResults": 216684,
"fuzzyLevel": 1,
"geoBias": {
"lat": 48.008446,
"lon": 7.821583
}
},
"results": [
{
"type": "POI",
"id": "DE/POI/p0/1505647",
"score": 2.574,
"dist": 774.6544330765787,
"info": "search:ta:276009006412786-DE",
"poi": {
"name": "Universität Freiburg Medizinische Fakultät",
"phone": "+(49)-(761)-27072350",
"url": "www.med.uni-freiburg.de",
"categories": [
"college/university"
],
"classifications": [
{
"code": "COLLEGE_UNIVERSITY",
"names": [
{
"nameLocale": "en-US",
"name": "college/university"
}
]
}
]
},
"address": {
"streetName": "Elsässer Straße",
"municipalitySubdivision": "Mooswald",
"municipality": "Freiburg im Breisgau",
"countrySecondarySubdivision": "Freiburg im Breisgau",
"countrySubdivision": "Baden-Württemberg",
"postalCode": "79110",
"countryCode": "DE",
"country": "Germany",
"countryCodeISO3": "DEU",
"freeformAddress": "Elsässer Straße, 79110 Freiburg Im Breisgau"
},
"position": {
"lat": 48.00894,
"lon": 7.83197
},
"viewport": {
"topLeftPoint": {
"lat": 48.00984,
"lon": 7.83063
},
"btmRightPoint": {
"lat": 48.00804,
"lon": 7.83331
}
},
"entryPoints": [
{
"type": "main",
"position": {
"lat": 48.00931,
"lon": 7.83259
}
}
]
}
]
}
Step 1:
Parse your JSON in a JSON parser website such as https://jsonparser.org
This will help you understand the content and how it will be translated as an object.
For example, your JSON string gives this result :
Step2:
Open the query tool of this website, this will help you find out the object path to the information you need.
For example, for your JSON string, to access the POI name :
Step 3:
In your Visual Studio project, install the NuGet package: Newtonsoft.Json and Microsoft.CSharp in your shared library.
If you are processing the JSON in a separate library, please also install the Newtonsoft.Json NuGet package in the main project.
Step 4:
If JSONstring is your JSON string :
using Newtonsoft.Json;
dynamic NewObject = JsonConvert.DeserializeObject<dynamic>(JSONstring);
string Name = NewObject.results[0].poi.name;
string Distance = NewObject.results[0].dist;
You have at least 2 solutions possible:
Either you create classes that mirror the content of the json you are expecting
public class MyJSON
{
public Summary summary { get; set; }
public List<Result> results { get; set; }
...
}
public class Summary
{
public string query { get; set; }
...
}
Then you could deserialize using Newtonsoft.Json
JsonConvert.DeserializeObject<MyJSON>(jsonstring);
Or you could directly deserialize to a dynamic object and access the properties directly by name.
dynamic data = JsonConvert.DeserializeObject<dynamic>(jsonstring);
string query = data[0].summary.query;
Solution 1 requires you to create the classes first, but is faster and more secure to access (less prone to wrong naming, or data structure changes)
Solution 2 is much more volatile and flexible, you just access what you need. But you could get exceptions if you try to access properties that do not exist in the json object.
i converted your json via json2csharp
then you can use Newtonsoft to deserialize them
RootObject root= JsonConvert.DeserializeObject(JSONstring)
public class GeoBias
{
public double lat { get; set; }
public double lon { get; set; }
}
public class Summary
{
public string query { get; set; }
public string queryType { get; set; }
public int queryTime { get; set; }
public int numResults { get; set; }
public int offset { get; set; }
public int totalResults { get; set; }
public int fuzzyLevel { get; set; }
public GeoBias geoBias { get; set; }
}
public class Name
{
public string nameLocale { get; set; }
public string name { get; set; }
}
public class Classification
{
public string code { get; set; }
public List<Name> names { get; set; }
}
public class Poi
{
public string name { get; set; }
public string phone { get; set; }
public string url { get; set; }
public List<string> categories { get; set; }
public List<Classification> classifications { get; set; }
}
public class Address
{
public string streetName { get; set; }
public string municipalitySubdivision { get; set; }
public string municipality { get; set; }
public string countrySecondarySubdivision { get; set; }
public string countrySubdivision { get; set; }
public string postalCode { get; set; }
public string countryCode { get; set; }
public string country { get; set; }
public string countryCodeISO3 { get; set; }
public string freeformAddress { get; set; }
}
public class Position
{
public double lat { get; set; }
public double lon { get; set; }
}
public class TopLeftPoint
{
public double lat { get; set; }
public double lon { get; set; }
}
public class BtmRightPoint
{
public double lat { get; set; }
public double lon { get; set; }
}
public class Viewport
{
public TopLeftPoint topLeftPoint { get; set; }
public BtmRightPoint btmRightPoint { get; set; }
}
public class Position2
{
public double lat { get; set; }
public double lon { get; set; }
}
public class EntryPoint
{
public string type { get; set; }
public Position2 position { get; set; }
}
public class Result
{
public string type { get; set; }
public string id { get; set; }
public double score { get; set; }
public double dist { get; set; }
public string info { get; set; }
public Poi poi { get; set; }
public Address address { get; set; }
public Position position { get; set; }
public Viewport viewport { get; set; }
public List<EntryPoint> entryPoints { get; set; }
}
public class RootObject
{
public Summary summary { get; set; }
public List<Result> results { get; set; }
}
Related
I have a JSON API result that I processed thru an online JSON-to-C# structure program to create the class structure. I've used this many times for other projects. The JSON returned everything along with a public class RootObject that references both the status and payload segments of the returned values.
I am using ASP.NET C# library to deserialize the result JSON using JavaScriptSerializer:
var vlist = new JavaScriptSerializer().Deserialize<TestStruct>(result);
My data structure looks like this (it's pretty standard):
public class TestStruct
{
public class Status
{
public int statusCode { get; set; }
public int errorType { get; set; }
public int errorCode { get; set; }
public string errorMessage { get; set; }
}
public class Payload
{
public VehicleStatusRpt vehicleStatusRpt { get; set; }
}
public class VehicleStatusRpt
{
public string statusType { get; set; }
//public ReportDate reportDate { get; set; }
//public VehicleStatus vehicleStatus { get; set; }
}
public class RootObject
{
public Status status { get; set; }
public Payload payload { get; set; }
}
}
The full JSON Result I'm trying to parse using the class structure is:
{
"status": {
"statusCode": 0,
"errorType": 0,
"errorCode": 0,
"errorMessage": "Success with response body"
},
"payload": {
"vehicleSummary": [
{
"vin": "KNDJX3AE8E7000080",
"vehicleIdentifier": "000080",
"modelName": "SOUL EV",
"modelYear": "2015",
"nickName": "My SOUL",
"generation": 1,
"extColorCode": "1D",
"trim": "EV",
"imagePath": {
"imageName": "2015-soul_ev-ev-1d.png",
"imagePath": "/content/dam/kia/us/owners/image/vehicle/2015/soul_ev/ev/",
"imageType": "1",
"imageSize": {
"length": "100",
"width": "100",
"uom": 0
}
},
"enrollmentStatus": 1,
"fatcAvailable": 1,
"telematicsUnit": 1,
"fuelType": 4,
"colorName": "CLEAR WHITE",
"activationType": 1,
"mileage": "24410",
"dealerCode": "MOBISDLR1",
"mobileStore": [
{
"osType": 0,
"downloadURL": "https://itunes.apple.com/us/app/kia-access-with-uvo-link/id1280548773?mt=8",
"image": {
"imageName": "iosImage.png",
"imagePath": "/content/dam/kia/us/owners/image/common/app/",
"imageType": "2",
"imageSize": {
"length": "100",
"width": "100",
"uom": 0
}
}
},
{
"osType": 1,
"downloadURL": "https://play.google.com/store/apps/details?id=com.myuvo.link",
"image": {
"imageName": "androidImage.png",
"imagePath": "/content/dam/kia/us/owners/image/common/app/",
"imageType": "2",
"imageSize": {
"length": "100",
"width": "100",
"uom": 0
}
}
}
],
"supportedApp": {
"appType": "5",
"appImage": {
"imageName": "app-access.png",
"imagePath": "/content/dam/kia/us/owners/image/common/app/access/",
"imageType": "2",
"imageSize": {
"length": "100",
"width": "100",
"uom": 0
}
}
},
"supportAdditionalDriver": 0,
"customerType": 0,
"vehicleKey": "937db044-8328-4188-a3d2-68ac3b183752"
}
]
}
}
I run this thru json2csharp.com to get the structure (the sample above is an abbreviated 'test' only
The deserializer returns an error: Invalid JSON Primitive (starting with Payload)
I see examples of using RootObject but with the Newtonsoft JSON libary. I would like to use the Microsoft library. Do I really need to switch to Newtonsoft JSON? If I can use JavaScriptSerializer library, how?
The classes that correspond to the JSON you posted are:
public class RootObject
{
public Status status { get; set; }
public Payload payload { get; set; }
}
public class Status
{
public int statusCode { get; set; }
public int errorType { get; set; }
public int errorCode { get; set; }
public string errorMessage { get; set; }
}
public class Payload
{
public List<VehicleSummary> vehicleSummary { get; set; }
}
public class VehicleSummary
{
public string vin { get; set; }
public string vehicleIdentifier { get; set; }
public string modelName { get; set; }
public string modelYear { get; set; }
public string nickName { get; set; }
public int generation { get; set; }
public string extColorCode { get; set; }
public string trim { get; set; }
public Image imagePath { get; set; }
public int enrollmentStatus { get; set; }
public int fatcAvailable { get; set; }
public int telematicsUnit { get; set; }
public int fuelType { get; set; }
public string colorName { get; set; }
public int activationType { get; set; }
public string mileage { get; set; }
public string dealerCode { get; set; }
public List<MobileStore> mobileStore { get; set; }
public SupportedApp supportedApp { get; set; }
public int supportAdditionalDriver { get; set; }
public int customerType { get; set; }
public string vehicleKey { get; set; }
}
public class Image
{
public string imageName { get; set; }
public string imagePath { get; set; }
public string imageType { get; set; }
public ImageSize imageSize { get; set; }
}
public class ImageSize
{
public string length { get; set; }
public string width { get; set; }
public int uom { get; set; }
}
public class MobileStore
{
public int osType { get; set; }
public string downloadURL { get; set; }
public Image image { get; set; }
}
public class SupportedApp
{
public string appType { get; set; }
public Image appImage { get; set; }
}
I was able to deserialize the JSON just fine using JavaScriptSerializer like this:
var root = new JavaScriptSerializer().Deserialize<RootObject>(result);
where result is the JSON string you posted in your question.
Note, however, that if you have placed your classes inside another class called TestStruct then you would need to take that into account and deserialize to TestStruct.RootObject instead, e.g.:
var root = new JavaScriptSerializer().Deserialize<TestStruct.RootObject>(result);
I was also able to deserialize the JSON using Json.Net in the same way with the JsonConvert class:
var root = JsonConvert.DeserializeObject<RootObject>(result);
Once you have the deserialized object, you can extract some interesting information from it like this:
foreach (var vs in root.payload.vehicleSummary)
{
Console.WriteLine(string.Format("{0} - {1} {2} {3}, {4} mi",
vs.vin, vs.colorName, vs.modelYear, vs.modelName, vs.mileage));
}
Here is a working demo using Json.Net: https://dotnetfiddle.net/Zh35be
I'm trying to deserialize a dynamic JSON (from API) to the correct objects, however some items do not have a type. In the example JSON, the "fulfillment" property has the values "F1" and "F2" and could have more (problem one). Within them, item properties have products order information, but do not have an item type, starting with the product name (ie "03.64.0005_11_10") that can be thousands of options (problem two).
How do I deserialise this JSON to fill in the correct objects? I tried RestCharp, Json.net, but I always get stuck on products property that I can not read and fill dynamically.
I tried the answers below, but no success:
How I deserialize a dynamic json property with RestSharp in C#?
Deserialize JSON into C# dynamic object?
Can you help me please?
"billingAddress": {
"zip": "64001340",
"state": "PI",
"number": "3443",
"status": "ACTIVE",
"firstName": "Fulano",
"telephone": {
"type": "billing",
"number": "88112244"
},
"neighbourhood": "Centro"
},
"clientId": "cliente3",
"documents": [
{
"type": "cpf",
"number": "12345678901"
}
],
"fulfillments": {
"F1": {
"id": "F1",
"orderId": "4017116",
"channelId": "channel2",
"clientId": "cliente3",
"locationId": "708",
"shipment": {
"method": "Economica",
"carrierName": "Transportadora"
},
"status": "CANCELED",
"type": "SHIPMENT",
"enablePrePicking": false,
"items": {
"03.64.0005_11_10": {
"sku": "03.64.0005_11_10",
"quantity": 0,
"stockType": "PHYSICAL",
"orderedQuantity": 1,
"returnedQuantity": 0,
"canceledQuantity": 1,
"itemType": "OTHER",
"presale": false,
"enablePicking": true
},
"18.06.0220_48_2": {
"sku": "18.06.0220_48_2",
"quantity": 0,
"stockType": "PHYSICAL",
"orderedQuantity": 1,
"returnedQuantity": 0,
"canceledQuantity": 1,
"itemType": "OTHER",
"presale": false,
"enablePicking": true
}
}
},
"F2": {
"id": "F2",
"orderId": "4017116",
"channelId": "channel2",
"clientId": "cliente3",
"locationId": "003",
"operator": {
"id": "5188",
"name": "Loja da Vila"
},
"ownership": "oms",
"shipment": {
"method": "Economica",
"carrierName": "Transportadora"
},
"status": "SHIPPING_READY",
"type": "SHIPMENT",
"enablePrePicking": true,
"items": {
"18.04.1465_01_3": {
"sku": "18.04.1465_01_3",
"quantity": 1,
"stockType": "PHYSICAL",
"orderedQuantity": 1,
"returnedQuantity": 0,
"canceledQuantity": 0,
"itemType": "OTHER",
"presale": false,
"enablePicking": true
},
"18.16.0630_13_10": {
"sku": "18.16.0630_13_10",
"quantity": 1,
"stockType": "PHYSICAL",
"orderedQuantity": 1,
"returnedQuantity": 0,
"canceledQuantity": 0,
"itemType": "OTHER",
"presale": false,
"enablePicking": true
}
}
}
},
"createdAt": "2019-06-08T21:41:12.000Z",
"updatedAt": "2019-06-08T21:41:12.000Z"
}
To
public class BillingAddress
{
public string zip { get; set; }
public string state { get; set; }
public string number { get; set; }
public string status { get; set; }
public string firstName { get; set; }
public Telephone telephone { get; set; }
public string neighbourhood { get; set; }
}
public class Fulfillment
{
public string id { get; set; }
public string orderId { get; set; }
public string channelId { get; set; }
public string clientId { get; set; }
public string locationId { get; set; }
public Shipment shipment { get; set; }
public string status { get; set; }
public string type { get; set; }
public bool enablePrePicking { get; set; }
public List<Item> items { get; set; }
}
public class Item
{
public string sku { get; set; }
public int quantity { get; set; }
public string stockType { get; set; }
public int orderedQuantity { get; set; }
public int returnedQuantity { get; set; }
public int canceledQuantity { get; set; }
public string itemType { get; set; }
public bool presale { get; set; }
public bool enablePicking { get; set; }
}
If the problem is just that the keys are dynamic but the structure of those dynamically-keyed objects are well-defined, then you can use a Dictionary<string, T> (instead of a List<T>) to handle the dynamic keys. From your sample JSON it looks like this is the case. So you would need a dictionary for the fulfillments at the root level and the items within the fulfillments. Your classes should look like this:
public class RootObject
{
public BillingAddress billingAddress { get; set; }
public string clientId { get; set; }
public List<Document> documents { get; set; }
public Dictionary<string, Fulfillment> fulfillments { get; set; }
public DateTime createdAt { get; set; }
public DateTime updatedAt { get; set; }
}
public class BillingAddress
{
public string zip { get; set; }
public string state { get; set; }
public string number { get; set; }
public string status { get; set; }
public string firstName { get; set; }
public Telephone telephone { get; set; }
public string neighbourhood { get; set; }
}
public class Telephone
{
public string type { get; set; }
public string number { get; set; }
}
public class Document
{
public string type { get; set; }
public string number { get; set; }
}
public class Fulfillment
{
public string id { get; set; }
public string orderId { get; set; }
public string channelId { get; set; }
public string clientId { get; set; }
public string locationId { get; set; }
public Operator #operator { get; set; }
public string ownership { get; set; }
public Shipment shipment { get; set; }
public string status { get; set; }
public string type { get; set; }
public bool enablePrePicking { get; set; }
public Dictionary<string, Item> items { get; set; }
}
public class Operator
{
public string id { get; set; }
public string name { get; set; }
}
public class Shipment
{
public string method { get; set; }
public string carrierName { get; set; }
}
public class Item
{
public string sku { get; set; }
public int quantity { get; set; }
public string stockType { get; set; }
public int orderedQuantity { get; set; }
public int returnedQuantity { get; set; }
public int canceledQuantity { get; set; }
public string itemType { get; set; }
public bool presale { get; set; }
public bool enablePicking { get; set; }
}
Then deserialize the JSON into the RootObject class:
var root = JsonConvert.DeserializeObject<RootObject>(json);
Here is a working demo: https://dotnetfiddle.net/xReEQh
Yea that structure really isn't meant to work like that with JSON. Looks like the fulfillments property should have been an array of those objects instead of having those numbered properties. Kind of looks like this is being auto-generated from an EDI file or something, even with that most of the good conversion tools are smart enough not to do this.
Option A: See if whoever is generating that file for you can correct their process.
Option B: If that is not possible, make your fulfillments property a Dictionary type where fulfillment is the class you have for that inner fulfillment object. That would then deserialize it "properly" and would give you a dictionary you can reference using the "F1" key up to "FN" but ideally you would create a list or array from your dictionary when using it. Even if order mattered you always have the id field to sort by later.
// Property on you deserialization object
public Dictionary<string, Fullfillment> fulfillmentDictionary {get; set;}
// Creating the list for easier use of the data
List<Fullfillment> fulfillments = fulfillmentDictionary.Values.ToList();
Similar logic would apply to your item lists.
For JSON messages with dynamic keys (i.e. changing from message to message) you should start with decoding into dynamic C# objects. One decoded (most JSON parsers support it) you enumerate every dynamic property, then convert its value into a POCO like Fulfillment, Item, etc (or just continue to work with the dynamic object).
Here is an example that works with your JSON https://dotnetfiddle.net/U5NfzC
I'm a little confused on the best way to parse the following JSON structure.
{
"featured": {
"id": 15,
"title": "media 1 -> 7",
"description": "test1",
"short_description": "test1",
"rating_avg": 0.0,
"image": "//d25xdrj7gd7wz1.cloudfront.net/covers/1603/1452024324.jpg"
},
"categories": [
{
"id": 1,
"title": "category 0",
"description": null,
"position": 0,
"media": [
{
"id": 1,
"title": "media 0 -> 0",
"description": "test1",
"short_description": "test1",
"rating_avg": 0.0,
"image": "//d25xdrj7gd7wz1.cloudfront.net/covers/1603/1452024324.jpg",
"category_media": {
"position": 0,
"category_id": 1,
"media_id": 1,
"id": 1
}
}, ...
Basically I have an array of categories which contains an array of medias (the featured is for something else)
I am looking to return List and the Category object contains a List
and I created some models:
public class Category
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public List<Media> MediaList { get; set; }
}
public class Media
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ShortDescription { get; set; }
public string Image { get; set; }
}
..and I am supposed to use Newtonsoft?
I looked at the following example: Deserializing Partial JSON Fragments but I would think I don't need to convert from JToken -> Category ... etc. In other words, I would think it would be easy to just return my List.
I'm new to LINQ (I come from a python background) so I'm getting to know C#
Use This as your Model
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class JsonModel
{
[JsonProperty("featured")]
public Featured Featured { get; set; }
[JsonProperty("categories")]
public List<Category> Categories { get; set; }
}
public partial class Category
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("description")]
public object Description { get; set; }
[JsonProperty("position")]
public long Position { get; set; }
[JsonProperty("media")]
public List<Featured> Media { get; set; }
}
public partial class Featured
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("short_description")]
public string ShortDescription { get; set; }
[JsonProperty("rating_avg")]
public long RatingAvg { get; set; }
[JsonProperty("image")]
public string Image { get; set; }
[JsonProperty("category_media", NullValueHandling = NullValueHandling.Ignore)]
public CategoryMedia CategoryMedia { get; set; }
}
public partial class CategoryMedia
{
[JsonProperty("position")]
public long Position { get; set; }
[JsonProperty("category_id")]
public long CategoryId { get; set; }
[JsonProperty("media_id")]
public long MediaId { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
}
}
Then do this in your Class:
var info = JsonConvert.DeserializeObject<JsonModel>(json);
var featured = info.Featured;
var categories = info.Categories;
You don't need LINQ in this case unless you want to change the data structure. To parse json file to list you have to create a class that matches a structure of your file, like:
class DataModel
{
public Featured Featured { get; set; }
public List<Category> Categories { get;set; }
}
Also, please pay attention that you need to use attribute [JsonProperty(PropertyName="fieldName")] if property name in json is different from property name in class.
And finally, to parse the data use the following row:
var data = JsonConvert.DeserializeObject<DataModel>(jsonString);
Act as follow:
Update your models with:
public class Category
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public List<Media> Media { get; set; }
}
public class Media
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ShortDescription { get; set; }
public string Image { get; set; }
}
public class Featured
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Short_Description { get; set; }
}
And then make a model same as your JSON structure:
public class YOUR_MODEL
{
public Featured Featured { get; set; }
public List<Category> Categories { get;set; }
}
And then Descrilize your JSON to your object:
YOUR_MODELresults = JsonConvert.DeserializeObject<YOUR_MODEL>(YOUR_JSON);
To get your model you can use tool like :
https://jsonutils.com/ or http://json2csharp.com/
In case of need you can also validate json syntax with : https://jsonlint.com/ to get detailed errors.
With a slightly modified version of your example, I get :
public class CategoryMedia
{
public int position { get; set; }
public int category_id { get; set; }
public int media_id { get; set; }
public int id { get; set; }
}
public class Medium
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string short_description { get; set; }
public double rating_avg { get; set; }
public string image { get; set; }
public CategoryMedia category_media { get; set; }
}
public class Category
{
public int id { get; set; }
public string title { get; set; }
public object description { get; set; }
public int position { get; set; }
public IList<Medium> media { get; set; }
}
public class Featured
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string short_description { get; set; }
public double rating_avg { get; set; }
public string image { get; set; }
public IList<Category> categories { get; set; }
}
public class Example
{
public Featured featured { get; set; }
}
It spares a lot of time for creating models and it allows you to verify that you don't have typos in field names.
With this, you just have to deserialize your JSON sample to "Example" class, using the library of your choice. Newtonsoft Json is a very efficient classical !
Newtonsoft is the standard for doing work like this. So lets look at the best way to do this. First lets start with your json format and fix it so you can use the online tools available to create a good model structure:
[
{
"featured": {
"id": 15,
"title": "media 1 -> 7",
"description": "test1",
"short_description": "test1",
"rating_avg": 0.0,
"image": "//d25xdrj7gd7wz1.cloudfront.net/covers/1603/1452024324.jpg"
},
"categories": [
{
"id": 1,
"title": "category 0",
"description": null,
"position": 0,
"media": [
{
"id": 1,
"title": "media 0 -> 0",
"description": "test1",
"short_description": "test1",
"rating_avg": 0.0,
"image": "//d25xdrj7gd7wz1.cloudfront.net/covers/1603/1452024324.jpg",
"category_media": {
"position": 0,
"category_id": 1,
"media_id": 1,
"id": 1
}
}
]
}
]
}
]
Now if you plug that into http://json2csharp.com/, it will output a good model structure:
public class Featured
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string short_description { get; set; }
public double rating_avg { get; set; }
public string image { get; set; }
}
public class CategoryMedia
{
public int position { get; set; }
public int category_id { get; set; }
public int media_id { get; set; }
public int id { get; set; }
}
public class Medium
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string short_description { get; set; }
public double rating_avg { get; set; }
public string image { get; set; }
public CategoryMedia category_media { get; set; }
}
public class Category
{
public int id { get; set; }
public string title { get; set; }
public object description { get; set; }
public int position { get; set; }
public List<Medium> media { get; set; }
}
public class RootObject
{
public Featured featured { get; set; }
public List<Category> categories { get; set; }
}
Feel free to rename RootObject So now lets look are how you can deserialize your json into your model objects using Newtonsoft:
Firstly you need to get your json file into a string format, so lets say its a file on your computer or in your project, there is many ways to retrieve it, either using Assembly, or Directory methods. Once you have access to your json file, read out the contents and then using Newtonsoft method for deserialising:
var myString = File.ReadAllText(path)
var myObject = JsonConvert.DeserializeObject<RootObject>(myString);
And thats it:P
How can we extract or retrieve child nodes values from JSON structure in C#.
my app is using OpenWeatherMap, I need to retrieve name from city, temp from list and description from weather nodes, my JSON and Class structure are below
{
"cod": "200",
"message": 0.0284,
"city": {
"id": 2643743,
"name": "London",
"coord": {
"lon": -0.12574,
"lat": 51.50853
},
"country": "GB",
"population": 0,
"sys": {
"population": 0
}
},
"cnt": 1,
"list": [
{
"dt": 1429268400,
"temp": {
"day": 12.21,
"min": 4.86,
"max": 13.18,
"night": 4.86,
"eve": 11.76,
"morn": 12.21
},
"pressure": 1028.8,
"humidity": 66,
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04d"
}
],
"speed": 5.9,
"deg": 67,
"clouds": 80
}
]
}
C# Class
public class WeatherForeCast
{
public string City { get; set; }
public decimal Day { get; set; }
public decimal Min { get; set; }
public decimal Max { get; set; }
public decimal Night { get; set; }
public string Description { get; set; }
}
Till date I'm familiar with using JSON.net for serialize and deserialize C# objects to JSON which has exact same structure.
If you just want to populate an instance of WeatherForecast, you could use a few SelectToken calls on a plain JObject:
var parsed = JObject.Parse(json);
var forecast = new WeatherForeCast();
forecast.City = parsed.SelectToken("city.name").Value<string>();
forecast.Day = parsed.SelectToken("list[0].temp.day").Value<decimal>();
forecast.Description = parsed.SelectToken("list[0].weather[0].description").Value<string>();
forecast.Min = parsed.SelectToken("list[0].temp.min").Value<decimal>();
forecast.Max = parsed.SelectToken("list[0].temp.max").Value<decimal>();
forecast.Night = parsed.SelectToken("list[0].temp.night").Value<decimal>();
Note that this is pretty brittle though, it's making assumptions about the contents of the JSON. If the JSON changes, the path to various properties in SelectToken will be incorrect and this code will throw an exception.
Use json2csharp.com to generate your classes.
public class Coord
{
public double lon { get; set; }
public double lat { get; set; }
}
public class Sys
{
public int population { get; set; }
}
public class City
{
public int id { get; set; }
public string name { get; set; }
public Coord coord { get; set; }
public string country { get; set; }
public int population { get; set; }
public Sys sys { get; set; }
}
public class Temp
{
public double day { get; set; }
public double min { get; set; }
public double max { get; set; }
public double night { get; set; }
public double eve { get; set; }
public double morn { get; set; }
}
public class Weather
{
public int id { get; set; }
public string main { get; set; }
public string description { get; set; }
public string icon { get; set; }
}
public class List
{
public int dt { get; set; }
public Temp temp { get; set; }
public double pressure { get; set; }
public int humidity { get; set; }
public List<Weather> weather { get; set; }
public double speed { get; set; }
public int deg { get; set; }
public int clouds { get; set; }
}
public class RootObject
{
public string cod { get; set; }
public double message { get; set; }
public City city { get; set; }
public int cnt { get; set; }
public List<List> list { get; set; }
}
Then use JSON.NET to deserialize into the class structure and extract the properties you want.
var jsonObject = JsonConvert.DeserializeObject<RootObject>(jsonString);
You now have an instance of RootObject and you can traverse it as needed to extract the specific value(s) you need.
How should my C# sharp object look like, I would like to deserialize the following JSON string to a C# object.
{
"PersonId": "XXXXXXXXXXXXXX",
"Name": "XXXXXXXX",
"HobbiesCollection":
{"Hobby":
[
{
"type": "RUNNING",
"id": 44,
"description": "sprinting and sprinting?"
},
{
"type": "RUNNING",
"id": 45,
"description": "jogging and jogging"
}
]
}
}
Here is what is generated in VS2013
public class Rootobject
{
public string PersonId { get; set; }
public string Name { get; set; }
public Hobbiescollection HobbiesCollection { get; set; }
}
public class Hobbiescollection
{
public Hobby[] Hobby { get; set; }
}
public class Hobby
{
public string type { get; set; }
public int id { get; set; }
public string description { get; set; }
}
You can use VS2012/2013 feature Edit/Paste Special/Paste JSON As Classes to simplify this process.
There is a online tool you can make C# class from your String
JSON to Csharp
public class Hobby
{
public string type { get; set; }
public int id { get; set; }
public string description { get; set; }
}
public class HobbiesCollection
{
public List<Hobby> Hobby { get; set; }
}
public class RootObject
{
public string PersonId { get; set; }
public string Name { get; set; }
public HobbiesCollection HobbiesCollection { get; set; }
}