I have the code below and I want to select the child note when I am accessing 'a'.
But the string result is returning null when I select the 'character' node
JObject jObj = (JObject)JsonConvert.DeserializeObject(strJson);
Assert.IsTrue(response.IsSuccessStatusCode.Equals(true));
var a = (JArray)jObj["cast"];
string result = (string)a.SelectToken("character");
This is the JSON response i get from 'a':
{[
{
"character": "Eddard Stark",
"credit_id": "5256c8ad19c2956ff60478a6",
"id": 48,
"name": "Sean Bean",
"profile_path": "/iIxP2IzvcLgr5WaTBD4UfSqaV3q.jpg",
"order": 0
},
{
"character": "Jon Snow",
"credit_id": "5256c8af19c2956ff6047af6",
"id": 239019,
"name": "Kit Harington",
"profile_path": "/dwRmvQUkddCx6Xi7vDrdnQL4SJ0.jpg",
"order": 0
},
{
"character": "Robert Baratheon",
"credit_id": "5256c8ad19c2956ff60478e2",
"id": 13633,
"name": "Mark Addy",
"profile_path": "/tGWYaLPIGvPJiKx9KzTBMITo7uK.jpg",
"order": 1
},
{
"character": "Daenerys Targaryen",
"credit_id": "5256c8af19c2956ff60479f6",
"id": 1223786,
"name": "Emilia Clarke",
"profile_path": "/tB1nE2LJH81f5UMiGhKCSlaqsF1.jpg",
"order": 1
},
{
"character": "Tyrion Lannister",
"credit_id": "5256c8b219c2956ff6047cd8",
"id": 22970,
"name": "Peter Dinklage",
"profile_path": "/xuB7b4GbARu4HN6gq5zMqjGbkwF.jpg",
"order": 2
}
]}
Your JSON seems to be incorrect, you have to remove begin and end curly braces.
Correct JSON:
[{
"character": "Eddard Stark",
"credit_id": "5256c8ad19c2956ff60478a6",
"id": 48,
"name": "Sean Bean",
"profile_path": "/iIxP2IzvcLgr5WaTBD4UfSqaV3q.jpg",
"order": 0
}, {
"character": "Jon Snow",
"credit_id": "5256c8af19c2956ff6047af6",
"id": 239019,
"name": "Kit Harington",
"profile_path": "/dwRmvQUkddCx6Xi7vDrdnQL4SJ0.jpg",
"order": 0
}, {
"character": "Robert Baratheon",
"credit_id": "5256c8ad19c2956ff60478e2",
"id": 13633,
"name": "Mark Addy",
"profile_path": "/tGWYaLPIGvPJiKx9KzTBMITo7uK.jpg",
"order": 1
}, {
"character": "Daenerys Targaryen",
"credit_id": "5256c8af19c2956ff60479f6",
"id": 1223786,
"name": "Emilia Clarke",
"profile_path": "/tB1nE2LJH81f5UMiGhKCSlaqsF1.jpg",
"order": 1
}, {
"character": "Tyrion Lannister",
"credit_id": "5256c8b219c2956ff6047cd8",
"id": 22970,
"name": "Peter Dinklage",
"profile_path": "/xuB7b4GbARu4HN6gq5zMqjGbkwF.jpg",
"order": 2
}]
Equivalent Model class:
public class SampleClass
{
public string character { get; set; }
public string credit_id { get; set; }
public int id { get; set; }
public string name { get; set; }
public string profile_path { get; set; }
public int order { get; set; }
}
Deserialize using the below code:
It will give you List or Array of SampleClass object. You can use foreach loop or LINQ to get all the character field.
List<SampleClass> lsObj = JsonConvert.DeserializeObject<List<SampleClass>>(strJson);
foreach(SampleClass obj in lsObj)
{
string character = obj.character;
}
First you have to create model class You can use http://json2csharp.com/, and deserialize it using Json.NET
use the following namespace
using Newtonsoft.Json;
model class and DeserializeObject method
public class RootObject
{
public string character { get; set; }
public string credit_id { get; set; }
public int id { get; set; }
public string name { get; set; }
public string profile_path { get; set; }
public int order { get; set; }
}
var x =JsonConvert.DeserializeObject<List<RootObject>>(myjsondata);
var character = x[index].character;
Well, you ca just parse your string to JObject directly with JObject.Parse() method or JArray.Parse(). Then you can just iterate through you array and get array objects by index: jsonObj[0]. And if you want get some specific value of that object - use Value<T>() method^ jsonObj[0].Value<string>("character")
Related
I am attempting to deserialize a tree of JSon objects I get back into a DTO. The tree can be up to 4 levels deep, and over 1200 nodes. The code is C# using Newtonsoft.Json for deserialization.
EDIT
The JSon looks like:
[
{
"id": 1095,
"name": "Item1-1",
"children": [
{
"id": 1097,
"name": "Item2-2",
"children": [
{
"id": 18,
"name": "Item3-3",
"children": [
{
"id": 19,
"name": "Item4-4",
"children": [],
"level": 4,
"parentId": 18
},
{
"id": 20,
"name": "Item5-4",
"children": [],
"level": 4,
"parentId": 18
}
],
"level": 3,
"parentId": 1097
}
],
"level": 2,
"parentId": 1095
}
],
"level": 1,
"parentId": null
}
]
My DTO is similar to this:
public class MyDTO
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("children")]
public MyDTO[] Children { get; set; }
[JsonProperty("level")]
public int Level { get; set; }
[JsonProperty("parentId")]
public int ParentId { get; set; }
public MyDTO()
{
}
}
I like Brian Rogers' solution in this link, which deserializes the json into objects:
How do I use JSON.NET to deserialize into nested/recursive Dictionary and List?
public static class JsonHelper
{
public static object Deserialize(string json)
{
return ToObject(JToken.Parse(json));
}
private static object ToObject(JToken token)
{
switch (token.Type)
{
case JTokenType.Object:
return token.Children<JProperty>()
.ToDictionary(prop => prop.Name,
prop => ToObject(prop.Value));
case JTokenType.Array:
return token.Select(ToObject).ToList();
default:
return ((JValue)token).Value;
}
}
}
I call the JSonHelper with object obj = JsonHelper.Deserialize(jsonString);
I have been experimenting with converting this code into a method to convert to MyDTO, but I keep running into compiler errors. I have attempted to simply convert the JValue casts with MyDTO and move on to the List with a List.
My goal is to call MyDTO obj = JsonHelp.Deserialize(jsonString) and get the tree of MyDTO objects back. Is it possible to do what I am trying, or should I find a way to cast each object to MyDTO?
First your JSON is missing a brakcet ], then your model needs a nullable parentId. Making a couple simple changes you can then you JsonConvert.DeserializeObject<IEnumerable<MyDTO>>(json).
So your JSON should look like this:
[
{
"id": 1095,
"name": "Item1-1",
"children": [
{
"id": 1097,
"name": "Item2-2",
"children": [
{
"id": 18,
"name": "Item3-3",
"children": [
{
"id": 19,
"name": "Item4-4",
"children": [],
"level": 4,
"parentId": 18
},
{
"id": 20,
"name": "Item5-4",
"children": [],
"level": 4,
"parentId": 18
}
],
"level": 2,
"parentId": 1095
}],
}],
"level": 1,
"parentId": null
}
]
And can be deserialized with this model:
public class MyDTO
{
public int Id { get; set; }
public string Name { get; set; }
public MyDTO[] Children { get; set; }
public int Level { get; set; }
public int? ParentId { get; set; }
}
Using this code:
var dto = JsonConvert.DeserializeObject<IEnumerable<MyDTO>>(json);
I want to deserialize this json to a List of Product objects but i get this error:
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ShoppingList.Product]' 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.
This is my code:
{
"records": [
{
"id": "60",
"name": "Rolex Watch",
"description": "Luxury watch.",
"price": "25000",
"category_id": "1",
"category_name": "Fashion"
},
{
"id": "48",
"name": "Bristol Shoes",
"description": "Awesome shoes.",
"price": "999",
"category_id": "5",
"category_name": "Movies"
},
{
"id": "42",
"name": "Nike Shoes for Men",
"description": "Nike Shoes",
"price": "12999",
"category_id": "3",
"category_name": "Motors"
}
]
}
public class Product
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public decimal price { get; set; }
public int category_id { get; set; }
public string category_name { get; set; }
}
public async Task<List<Product>> GetProductsAsync()
{
Products = new List<Product>();
var uri = new Uri("https://hostname/api/product/read.php");
try
{
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
Products = JsonConvert.DeserializeObject<List<Product>>(content);
}
}
catch (Exception )
{
throw;
}
return Products;
}
Your Json is not a List<Product>, its an object with a single property called records which is a List<Product>.
So your actual C# model is this:
public class RootObject
{
public List<Product> records { get; set; }
}
And you deserialize like this:
RootObject productsRoot = JsonConvert.DeserializeObject<RootObject>(content);
The issue is that your response JSON you've provided is an object which contains a list, but you are trying to deserialize the data into a straight list. I think all you need to do is add a second class which contains the list into your code, then deserialize using that list.
public class Product
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public decimal price { get; set; }
public int category_id { get; set; }
public string category_name { get; set; }
}
public class RootProduct
{
public List<Product> Products {get;set;}
}
Then you change your deserialization portion from List to
RootProduct response = JsonConvert.DeserializeObject<RootProduct>(content);
The usage would then simply be products. response.Products to access the list of items.
The problem is your json structure. Below is an example of a json array - notice i removed the property "records".
[
{
"id": "60",
"name": "Rolex Watch",
"description": "Luxury watch.",
"price": "25000",
"category_id": "1",
"category_name": "Fashion"
},
{
"id": "48",
"name": "Bristol Shoes",
"description": "Awesome shoes.",
"price": "999",
"category_id": "5",
"category_name": "Movies"
},
{
"id": "42",
"name": "Nike Shoes for Men",
"description": "Nike Shoes",
"price": "12999",
"category_id": "3",
"category_name": "Motors"
}
]
Given this data
[
{
"id": "60",
"name": "Rolex Watch",
"description": "Luxury watch.",
"price": "25000",
"category_id": "1",
"category_name": "Fashion"
},
{
"id": "48",
"name": "Bristol Shoes",
"description": "Awesome shoes.",
"price": "999",
"category_id": "5",
"category_name": "Movies"
},
{
"id": "42",
"name": "Nike Shoes for Men",
"description": "Nike Shoes",
"price": "12999",
"category_id": "3",
"category_name": "Motors"
}
]
And this class definition
public class Order
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public string price { get; set; }
public string category_id { get; set; }
public string category_name { get; set; }
}
The code to convert it from JSON to a C# List<Order> is:
public static List<Order> Map(string json)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<List<Order>>(json);
}
im facing a problem with probably selfreference Looping:
Model:
public class ProtectedAccount
{
public int Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime Created { get; private set; }
public DateTime? Changed { get; set; }
public bool Disabled { get; set; }
public virtual ICollection<ProtectedAccountMember> Members { get; set; }
public virtual ProtectedAccountType Type { get; set; }
}
public class ProtectedAccountMember
{
public int Id { get; set; }
[StringLength(300)]
public string Name { get; set; }
[Index]
public virtual ProtectedAccount ProtectedAccount { get; set; }
}
Controller:
[ResponseType(typeof(ProtectedAccount))]
[Route("ProtectedAccounts/{id}/Members")]
[HttpGet]
public IHttpActionResult GetProtectedAccountMembers(int id)
{
var protectedAccount = db.ProtectedAccounts.Find(id);
if (protectedAccount == null)
{
return NotFound();
}
return Ok(protectedAccount.Members.ToList());
}
the data wich i receive for an GET seems to Loop recursive through all navigations:
[
{
"ProtectedAccount": {
"Members": [
{
"Id": 2,
"Name": "XXX, XX",
},
{
"Id": 3,
"Name": "XX, XX",
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXX",
},
"Id": 1,
"Name": "test",
},
{
"ProtectedAccount": {
"Members": [
{
"Id": 1,
"Name": "test",
},
{
"Id": 3,
"Name": "XX, XX",
"SamAccountName": "XX",
"Disabled": false
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXXX",
},
"Id": 2,
"Name": "XX, XX",
},
{
"ProtectedAccount": {a
"Members": [
{
"Id": 1,
"Name": "test",
"SamAccountName": "XXX",
"Disabled": false
},
{
"Id": 2,
"Name": "XX, XX",
"SamAccountName": "XX",
"Disabled": false
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXX",
},
"Id": 3,
"Name": "XX, XX",
}
]
There is only one "ProtectedAccount" in the database. DO i have to use DTO to overcome this issue? I tried some configuration via the json formatsettings but didnt get any better results.
From your code, you are only returing the protectedAccount.Members, hence you could do a projection query as below
var results = ctx.ProtectedAccountMembers
.Where(member => member.ProtectedAccount.Id == protectedAccount.Id)
.Select(member => new { member.Id, member.Name }).ToList();
I usually use json2csharp to generate json classes to c#. But I do have problem. My json is have dynamic depth like this
{
"kategori": [
{
"id": "1",
"namakategori": "Tips & Trick",
"parent_id": "0",
"children": [
{
"id": "348",
"namakategori": "Fotografi",
"parent_id": "1",
"children": []
},
{
"id": "370",
"namakategori": "Hacking",
"parent_id": "1",
"children": []
}
]
},
{
"id": "12",
"namakategori": "Aplikasi",
"parent_id": "0",
"children": [
{
"id": "13",
"namakategori": "Tools",
"parent_id": "12",
"children": [
{
"id": "14",
"namakategori": "Toolsorder",
"parent_id": "13",
"children":[]
},
]
},
]
},
]
}
So how do I generate json classes dynamically so it can be used for my json? In above example I have 3 depth. But if I go to different page maybe it have 4 or more depth.
You don't need to declere your classes dynamically. This should work:
public class Child
{
public string id { get; set; }
public string namakategori { get; set; }
public string parent_id { get; set; }
public List<Child> children { get; set; } // <-- See this
}
public class RootObj
{
public List<Child> kategori { set; get; }
}
To deserialize I'll use Json.Net
var res = JsonConvert.DeserializeObject<RootObj>(json);
You can always use the Newtonsoft.Json
For Instance,
JObject result = (JObject) JsonConvert.DeserializeObject(yourJsonDataHere);
var katObject = result.Property("kategori").Value;
and so on...
PS: Not sure if Newtonsoft.Json is supported on WP7.
I'm trying to deserialize a json string and I'm getting the error End element 'caption' from namespace '' expected. Found element 'created_time' from namespace ''. when calling
InstagramObject test = (InstagramObject) instagramObject.ReadObject(instagramWebResponse.GetResponseStream());
The json from Instagram returns many elements but there are only a few that I need. My DataContract will be posted below.
Basically I need {data:[{caption: string, link: string, images: {...}}]}
Here's an example of the json...
{
"data": [{
"comments": {
"data": [],
"count": 0
},
"caption": {
"created_time": "1296710352",
"text": "Inside le truc #foodtruck",
"from": {
"username": "kevin",
"full_name": "Kevin Systrom",
"type": "user",
"id": "3"
},
"id": "26621408"
},
"likes": {
"count": 15,
"data": [{
"username": "mikeyk",
"full_name": "Mike Krieger",
"id": "4",
"profile_picture": "..."
}, {...subset of likers...}]
},
"link": "http://instagr.am/p/BWrVZ/",
"user": {
"username": "kevin",
"profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_3_75sq_1295574122.jpg",
"id": "3"
},
"created_time": "1296710327",
"images": {
"low_resolution": {
"url": "http://distillery.s3.amazonaws.com/media/2011/02/02/6ea7baea55774c5e81e7e3e1f6e791a7_6.jpg",
"width": 306,
"height": 306
},
"thumbnail": {
"url": "http://distillery.s3.amazonaws.com/media/2011/02/02/6ea7baea55774c5e81e7e3e1f6e791a7_5.jpg",
"width": 150,
"height": 150
},
"standard_resolution": {
"url": "http://distillery.s3.amazonaws.com/media/2011/02/02/6ea7baea55774c5e81e7e3e1f6e791a7_7.jpg",
"width": 612,
"height": 612
}
},
"type": "image",
"filter": "Earlybird",
"tags": ["foodtruck"],
"id": "22721881",
"location": {
"latitude": 37.778720183610183,
"longitude": -122.3962783813477,
"id": "520640",
"street_address": "",
"name": "Le Truc"
}
}]
}
and here's my DataContract...
[DataContract]
public class InstagramObject {
[DataMember(Name = "data")]
public IEnumerable<InstagramData> instagramData { get; set; }
}
[DataContract]
public class InstagramData {
[DataMember(Name = "images")]
public List<InstagramImage> instagramImages { get; set; }
[DataMember(Name = "caption")]
public string caption { get; set; }
[DataMember(Name = "link")]
public string link { get; set; }
}
[DataContract]
public class InstagramImage {
[DataMember(Name = "low_resolution")]
public InstagramImageInfo lowResolutionImage { get; set; }
[DataMember(Name = "thumbnail")]
public InstagramImageInfo thumbnail { get; set; }
[DataMember(Name = "standard_resolution")]
public InstagramImageInfo standardResolution { get; set; }
}
[DataContract]
public class InstagramImageInfo {
[DataMember(Name = "url")]
public string url { get; set; }
[DataMember(Name = "width")]
public int width { get; set; }
[DataMember(Name = "height")]
public int height { get; set; }
}
In the data contract caption is declared as a string, but in the JSON caption is a record with various fields - caption should be declared to be an object with a compatible structure:
[DataContract]
public class InstagramCaption {
[DataMember(Name = "text")]
public string Text {get; set;}
}
. . .
[DataMember(Name = "caption")]
public InstagramCaption caption { get; set; }
. . .
No need to declare those clases If you want to go with Json.Net + Linq
var obj = (JObject)JsonConvert.DeserializeObject(json);
var result = obj["data"]
.Select(x => new {
Caption = (string)x["caption"]["text"],
Link = (string)x["link"],
Images = x["images"].Children()
.Select(y=>(string)y.First()["url"]).ToArray()
})
.ToArray();