Parsing nested JSON--child properties are null - c#

So I am trying to parse some JSON that is returned to me by a third party api that looks something like:
{
"status":"ok",
"links":
[
{
"link":
{
"link_name":"Sample",
"link_id":"9999"
}
},
],//and so on with other nested properties
I have created classes to map the JSON to
[DataContract]
public class JsonTestResults
{
[DataMember]
public string status { get; set; }
[DataMember]
public IEnumerable<Link> links { get; set; }
}
[DataContract]
public class Link
{
[DataMember]
public string link_name { get; set; }
[DataMember]
public string link_id { get; set; }
}
And I'm pushing the response through this deserializer (taken from this post
public T Deserialise<T>( string json )
{
T obj = Activator.CreateInstance<T>( );
using (MemoryStream ms = new MemoryStream( Encoding.Unicode.GetBytes( json ) ))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer( obj.GetType( ) );
obj = (T)serializer.ReadObject( ms );
return obj;
}
}
However, my deserialized results are showing the contents of Link[] as null. (there is a Link object for each one returned, but the link_name and link_id are null.)
I've checked out this, this, this, this and this, but haven't been able to solve this issue. I am looking for a solution that doesn't require a third party library. (per my lead dev).
I don't believe it's a problem with the classes matching the JSON, but I can post the full code if anyone would like to review it.

You need one more class to deserialize it correctly
public class JsonTestResults
{
public string status { get; set; }
public IEnumerable<TempLink> links { get; set; }
}
public class TempLink
{
public Link link;
}
public class Link
{
public string link_name { get; set; }
public string link_id { get; set; }
}
I tested it with Json.Net and worked.
var obj = JsonConvert.DeserializeObject <JsonTestResults>(json);
JavaScriptSerializer also works
var obj2 = new JavaScriptSerializer().Deserialize<JsonTestResults>(json);

Its a syntax error in the JSON,
In a JSON Array the last element does not have a ',' after it.
{
"status":"ok",
"links":
[
{
"link":
{
"link_name":"Sample",
"link_id":"9999"
}
}
],
This will work !!

Related

How to serialize a JsonArray with C#?

SO I have a Json array as following:
{[data, [{"name":"Micheal Jackson","pic_large":"https://scontent.x.fbcdn.net/v/t1.0-1/p200x200/14909900_10154513795037597_3241587822245799922_n.jpg?oh=54ead7e0ba74b45b632d96da1515ccf8&oe=591C4938","id":"10154729171332597"}
How can I serialize it with C# to parse it into objects and then pass it to the view.
EDIT:
{[data, [{"name":"Sayed Zubair Hashimi","pic_large":"https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/14909900_10154513795037597_3241587822245799922_n.jpg?oh=54ead7e0ba74b45b632d96da1515ccf8&oe=591C4938","id":"10154729171332597"},{"name":"Junaid Walizada","pic_large":"https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/14055012_1760562554217155_4937121194048198140_n.jpg?oh=376b49c9d04c2676ebe3d853b122165e&oe=58EA033D","id":"1821833754756701"},{"name":"Mohib Akhondzada","pic_large":"https://scontent.xx.fbcdn.net/v/t1.0-1/s200x200/14264218_592094647641140_6351146344336469735_n.jpg?oh=a8a63893d71f76c45fa3d07389f1700a&oe=59147C84","id":"648198542030750"},{"name":"Za Beah","pic_large":"https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/15741112_359701871054520_6692094260041596196_n.jpg?oh=6d9a0e73f70145b821c79cbe738090a0&oe=58E5B5B5","id":"360411140983593"},{"name":"Baser Nader","pic_large":"https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/15094436_10153876544626432_1550234361821853528_n.jpg?oh=e197fa712b3180a20612ecdacb01747c&oe=58E54DEC","id":"10153975726331432"},{"name":"Abasin Deniz","pic_large":"https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/15698075_440749809647293_7905213567074684088_n.jpg?oh=aeb22664f458d75fc00638ca6fa4ecfc&oe=591F7BB3","id":"444098429312431"}]]}
EDIT2:
Here is how I retrieve above Json.
var appsecret_proof = access_token.GenerateAppSecretProof();
var fb = new FacebookClient(access_token);
dynamic myFeed = await fb.GetTaskAsync(
("me/feed?fields=likes{{name,pic_large}}")
.GraphAPICall(appsecret_proof));
The strings shown in your question are all invalid JSON. A properly formatted JSON might look like this:
{
"data": [{
"name": "Micheal Jackson",
"pic_large": "https://scontent.x.fbcdn.net/v/t1.0-1/p200x200/14909900_10154513795037597_3241587822245799922_n.jpg?oh=54ead7e0ba74b45b632d96da1515ccf8&oe=591C4938",
"id": "10154729171332597"
}]
}
Now if you want to map this to C# class that's pretty easy to do. Just define the models to reflect this structure:
public class Feed
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("pic_large")]
public string PicLarge { get; set; }
}
public class Result
{
[JsonProperty("data")]
public IList<Feed> Feeds { get; set; }
}
and then all that's left is to deserialize the JSON string using a JSON serializer such as Json.NET back to this object structure:
string json = ... the json string shown above
var result = JsonConvert.DeserializeObject<Result>(json);
foreach (var feed in result.Feeds)
{
Console.WriteLine(feed.Name);
}
first you need to create class with properties same as in json and then use the following code :
class obj
{
public string name {get ; set; }
public string pic_large {get ; set; }
public id {get ; set; }
}
using System.Web.Script.Serialization;
.
.
var obj = new JavaScriptSerializer().Deserialize<obj>(jsonString);

Runtime Binder Exception

After a deserialization I save the content in an object:
var obj = JsonConvert.DeserializeObject<dynamic>(responseText);
so I execute a loop for populate a DataGrid
foreach(var item in obj)
{
MainWindow.AppWindow.Squadre_DataGrid.Items.Add(new Teams.Club_Information
{
code = item.code,
name = item.name,
shortName = item.shortName,
squadMarketValue = item.squadMarketValue
});
}
The problem's that inside the foreach the compiler show Runtime Binder Exception.
Why happean this?
Some more details:
Class structure
public class Self
{
public string href { get; set; }
}
public class Fixtures
{
public string href { get; set; }
}
public class Players
{
public string href { get; set; }
}
public class Links
{
public Self self { get; set; }
public Fixtures fixtures { get; set; }
public Players players { get; set; }
}
public class RootObject
{
public Links _links { get; set; }
public string name { get; set; }
public string code { get; set; }
public string shortName { get; set; }
public string squadMarketValue { get; set; }
public string crestUrl { get; set; }
}
JSON structure:
{
"_links": {
"self": { "href": "http://api.football-data.org/alpha/teams/19" },
"fixtures": { "href": "http://api.football-data.org/alpha/teams/19/fixtures" },
"players": { "href": "http://api.football-data.org/alpha/teams/19/players" }
},
"name": "Eintracht Frankfurt",
"code": "SGE",
"shortName": "Eintr. Frankfurt",
"squadMarketValue": "75.475.000 ?",
"crestUrl": "http://upload.wikimedia.org/wikipedia/commons/0/04/Eintracht_Frankfurt_Logo.svg"
}
The object you are deserializing does not contain a property named code. So the line code = item.code causes an exception at runtime, because the Json.Net object behind the dynamic does not contain a value named code.
This means that the Json that you are parsing does not contain a property named code. Or else it only sometimes contains a property named code. In that case you'll have to either parse it is a JObject and check if the property exists or create an type do deserialize it into.'
Edit
Based on the Json that you posted along with the class structure it looks like you should just be deserializing directly into a RootObject class:
var obj = JsonConvert.DeserializeObject<RootObject>(responseText);
Or in any case you can still deserialize into a dynamic but you need to get rid of the foreach since you don't have a collection of RootObject
var obj = JsonConvert.DeserializeObject<dynamic>(responseText);
MainWindow.AppWindow.Squadre_DataGrid.Items.Add(new Teams.Club_Information
{
code = obj.code,
name = obj.name,
shortName = obj.shortName,
squadMarketValue = obj.squadMarketValue
});
Where you went wrong was the foreach. Since obj is dynamic there is no compiler error and the Json.Net JObject that is returned supports iteraction. But the that gives you back each of the property values, (e.g. _links, name, etc) on at a time, not the object that you are interested in.

Reading a JSON file from web page and convert it in List<Object> in C#

I'm facing some problems with the read of a JSON file, which is this one:
{
"giocatori": [
{
"Giocatore": "124",
"Cognome": "DE SANCTIS",
"Ruolo": "P",
"Squadra": "ROM"
},
{
"Giocatore": "140",
"Cognome": "MIRANTE",
"Ruolo": "P",
"Squadra": "PAR"
},
{
"Giocatore": "156",
"Cognome": "SKORUPSKI",
"Ruolo": "P",
"Squadra": "ROM"
}
],
"success": 1
}
What I want to get from this PHP is an List, where the Player's class with this attributes;
public string Giocatore;
public string Cognome;
public string Ruolo;
public string Squadra;
I don't know why, but I face some problems with the Microsoft.Json library, in particular with Json.DeserializeObject> method, which is not able to read that web page. Can you provide some hint how to obtain a List in C# of Player ? Thank you so much for your support !
Go to http://json2csharp.com/, post your JSON there, and get the following classes:
public class Giocatori
{
public string Giocatore { get; set; }
public string Cognome { get; set; }
public string Ruolo { get; set; }
public string Squadra { get; set; }
}
public class RootObject
{
public List<Giocatori> giocatori { get; set; }
public int success { get; set; }
}
To deserialize your JSON string with JavaScriptSerializer, do:
var root = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(jsonString);
var list = root.giocatori;
To deserialize your JSON string with Json.NET, a widely used, free, open source JSON serializer, download and install it according to the instructions on the home page and do:
var root = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsonString);
var list = root.giocatori;

Deserialize Json like { List : { [ ... ], [ ... ] } }

It's my first work with Json.
I've already installed Json.Net in my Visual Studio project and used to deserialize some simple string like this:
{
"A":"1",
"B":"2",
"C":"3"
}
With this code:
JToken token = JObject.Parse("{ "A":"1","B":"2","C":"3"}";
string aValue = token.SelectToken("A");
string aValue = token.SelectToken("B");
string aValue = token.SelectToken("C");
But I don't know how to do with a Json like this:
{
"LIST":[
{
"A":"value1",
"B":"value1",
"C":"value1"
}
{
"A":"value2",
"B":"value2",
"C":"value2"
}
{
"A":"value3",
"B":"value3",
"C":"value3"
}
],
"D":"value4",
"E":"value5",
"F":"value6"
}
How can get all elements of type and the other variable like D, E and F?
Thank you
The easiest way would be to create objects and deserialize into those:
public class Parent
{
public Child[] LIST { get; set; }
public string D { get; set; }
public string E { get; set; }
public string F { get; set; }
}
public class Child
{
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
}
Once you have your classes defined, deserializing your JSON is as easy as:
var p = JsonConvert.DeserializeObject<Parent>(json);
#Justin's answer is good and will work well. However, if you want to continue using the LINQ-to-JSON API style as you are doing now, here is how you can get all the info:
JToken token = JToken.Parse(jsonString);
foreach (JToken t in token["LIST"])
{
Console.WriteLine(t["A"]);
Console.WriteLine(t["B"]);
Console.WriteLine(t["C"]);
}
Console.WriteLine(token["D"]);
Console.WriteLine(token["E"]);
Console.WriteLine(token["F"]);

nested json c# object deserialization

i have the following json string (jsonString)
[
{
"name":"Fruits",
"references":[
{"stream":{"type":"reference","size":"original",id":"1"}},
],
"arts":[
{"stream":{"type":"art","size":"original","id":"4"}},
{"stream":{"type":"art","size":"medium","id":"9"}},
]
}
]
and the following C# objects
class Item
{
public string Name { get; set; }
public List<Stream> References { get; set; }
public List<Stream> Arts { get; set; }
public Item()
{
}
}
class Stream
{
public string Type { get; set; }
public string Size { get; set; }
public string Id { get; set; }
public Stream()
{
}
}
and the following code
Item item = JsonConvert.DeserializeObject<Item>(jsonString);
when I run the code, it creteas the correct number of references and arts, but each stream has null value (type = null, size = null).
is it posible to do this json.net deserializeobject method or should I manually deserialize ?
EDIT: Okay, ignore the previous answer. The problem is that your arrays (references and arts) contain objects which in turn contain the relevant data. Basically you've got one layer of wrapping too many. For example, this JSON works fine:
[
{
"name":"Fruits",
"references":[
{"Type":"reference","Size":"original","Id":"1"},
],
"arts":[
{"Type":"art","Size":"original","id":"4"},
{"type":"art","size":"medium","id":"9"},
]
}
]
If you can't change the JSON, you may need to introduce a new wrapper type into your object model:
public class StreamWrapper
{
public Stream Stream { get; set; }
}
Then make your Item class have List<StreamWrapper> variables instead of List<Stream>. Does that help?

Categories

Resources