I'm using Facebook C# sdk for desktop app. I'm getting the dynamic object and then extracting the name,id etc
dynamic result = fb.Get("/me");
string name=result.name;
Now problem is I can't extract the work information or favorite teams etc. I've used the required permissions, but unable to handle the dynamic object. It's in this format:
"languages": [
{
"id": "106502622718539",
"name": "Bānglā"
},
{
"id": "106059522759137",
"name": "English"
}
],
http://developers.facebook.com/tools/explorer/
Tried and searched a lot to get them. Found nothing. I've read that it comes in the form of array. Please help to extract those information through C# code..........
It looks like you might want:
dynamic result = fb.Get("/me");
foreach (dynamic language in result.languages)
{
Console.WriteLine("{0}: {1}", language.name, language.id);
}
Can't say I've used the Facebook SDK myself though.
Here is a golden rule on how to consume json data in Facebook C# SDK/SimleJson (internally Facebook C# SDK uses SimpleJson for json serializing/deserializing http://simplejson.codeplex.com/).
There are 3 possible types: Array, Json Object and privimitive types.
Array: Can be casted to IList<Object> or IList<dynamic>
JsonObject: key value pair - IDictionary<string, object>
primitive types: bool, string, long and double.
Since langauges is an array, you can use it as IList<object> and consume it in a for loop like mentioned by Json Skeet. You also get the benefit of other IList<T> features such as indexer and different properties of the array.
dynamic result = fb.Get("/me");
var langauges = result.languages;
var length = languages.Length;
var lang1 = languages[0];
var lang1Id = lang1["id"];
var lang1Name = lang1["name"];
var lang2 = langauges[1];
var lang2Id = lang2.id;
var lang2Name = lang2.name;
since lang1 and lang2 is a JsonObject you can either use indexer like lang1["id"] as you do in for IDictionary<string,object> or much easier use lang1.id.
Related
I am trying to deserialize an object that an API sends me, but when doing so I cannot extract the values.
My object as JSON looks like this:
{
"Obj":
{
"id":19,
"name":"test",
"email":"test#mail.com",
"password":"0439434dae91c10c3bc073af1e76addf8f57a30ce0a7de0438b3aaad34b85200d41d01078f2ee786b3130b4ed4e39e3e26090da5d9f87420454dfdd182761cce",
"city":"Texas",
"age":37,
"date":"2022-05-09T00:00:00",
"mp":0,
"du":0,
"active":false,
"userid":0,
"user":""
},
"message":null,
"error":false,
"information":
{
"menssages":"Ok, Results",
"error":false,
"success":true,
"userId":0,
"user":"",
"register":0,
"pages":0
}
}
My code:
result = GetWebRequest("api/ClientId/" + id);
object rest = new JavaScriptSerializer().DeserializeObject(result.ToString());
Dictionary<string, object> keys = (Dictionary<string, object>)((object)rest);
I'd suggest using JSON.Net for both performance as well as features.
var account = JsonConvert.DeserializeObject<Account>(jsonString);
If you're using ASP.NET Core (not quite clear from your question/tags), you can also use the built-in System.Text.Json:
var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString);
Both approaches are much cleaner as you're working with classes instead of a Dictionary. Not that a Dictionary is wrong in any sense, this is just not an optimal use case for it, in particular because you're dealing with nested instances. Though in general, typed access to the properties of your data is almost always a preferred solution.
I am new to C# and JSON and need some help in getting the Key name(s) in a list of a nested JSON object. The keys are dynamic so I won't necessarily know the keys.
sample code I've tried.
```
protected void test()
{
var mystring = #"{
""zone1"": {
""sites"": {
""site1"": {
""to"": ""email1"",
""subject"": ""subjecttxt"",
""link"": ""somesite""
},
""site2"": {
""to"": ""email1"",
""subject"": ""subject"",
""link"": ""somesite""
}
},
""zone2"": {
""to"": ""email1"",
""subject"": ""subject"",
""link"": ""somelink""
}}";
var rss = JObject.Parse(mystring);
foreach (var section in rss)
{
Console.Write(section.Key);
IList<JToken> result = rss["zone1"]["sites"].Children().ToList();
var zone = section.Key;
var site = rss[zone]["sites"];
foreach (var subsite in rss["zone1"]["sites"])
{
var subs = subsite.Parent.ToString();
// some other code
}
}
}
```
Looking for a result:
site1,
site2,
...
I can get the children as IList but looking for something similar to "section.Key" as noted above.
Thank you for your help.
I believe what you are looking for is to get the properties of the sites. Since accessing the rss["zone1"]["sites"] returns a JToken, you will need to convert that to JObject and then use Properties() method to get the data you need.
var sites = ((JObject)rss["zone1"]["sites"]).Properties();
Then you can simply iterate over the IEnumerable<Jproperty> to get the Name of the property or whatever else you need from under it.
To get the section.Key for the sites, you can use the following code.
foreach(var site in (JObject)rss["zone1"]["sites"]) {
Console.WriteLine(site.Key);
}
Output:
site1
site2
Your first call to JObject.Parse already does all the work of converting a string into a structured JSON object. The currently-accepted answer redoes some of this work by (1) turning a structured JSON object back into a string, and then (2) re-parsing it with JObject.Parse. There is a simpler way.
Instead, you can cast the value stored at rss["zone1"]["sites"] into a JObject. (The expression rss["zone1"]["sites"] has type JToken, which is a parent class of JObject, but in this case we happen to know that rss["zone1"]["sites"] is always JSON object, i.e. a collection of key-value pairs. Therefore, this cast is safe to perform.)
This is what the code might look like:
var sites = (JObject) rss["zone1"]["sites"];
foreach (var site in sites)
{
Console.WriteLine(site.Key);
}
Have to write a generic method which will take json of any structure and add new properties to each element with data
Structure # 1, (Person)
Input Json data,
{'name':'sam', 'age': 12}
Expected output,
{'name':'sam', 'name_xyz': 'Rob', 'age': 12, 'age_xyz': 15}
Structure # 2, (Person with address)
Input json data,
{ 'name': 'sam', address : { 'city': 'fishers', 'zip': 23456 } }
Expected output,
{'name': 'sam', 'name_xyz': 'rob', address : { 'city': 'fishers', 'city_xyz': 'fishers', 'zip': 23456, 'zip_xyz': 678768} }
Structure # 3 (Person's)
Input json data,
[{'name': 'sam'}, {'name':'rex'}]
Expected Output,
[{'name': 'sam', 'name_xyz': 'felix'}, {'name':'rex', 'name_xyz' : 'bob'}]
I have something for defined model using NewtonSoft, but I need generic method to parse and evaluate any type of json data.
var jsonData = JsonConvert.SerializeObject(modelData);
var jArray = JArray.Parse(jsonData) as JArray;
dynamic persons = jArray;
foreach (dynamic person in persons)
{
var name = person.name;
var newname = Getnewname(name);
person.Add(new JProperty("name_xyz", newname));
var age = person.age;
var newage = GetnewAge(age);
person.Add(new JProperty("age_xyz", newage));
}
var result = persons.ToString();
Things to consider,
Look for each node, determine if it is array or object
Found object, create new object at same level with same property post fix '_xyz'
Found Array, loop through each object and same step 2
It will be nth level depth
I have encountered a similar situation and I solved it using a "nested dictionary" approach. While it is always a pleasure to work in the comfort zone of strongly typed entities, there are times when creating C# classes might get too cumbersome. This was my situation.
Treat the entire JSON like a dictionary where one or more keys might store another Dictionary. And this might continue several levels deep. The method Jobject.Parse worked for me. The JObject works like a key-value collection and you can recursively retrieve more JObject instances as you traverse deeper.
Newtonsoft reference - flat dictionary
https://www.newtonsoft.com/json/help/html/SerializingCollections.htm
This will NOT work very well with a nested structure like yours.
Newtonsoft code snippet - parsing as a JObject
string json="[{'name': 'sam', 'name_xyz': 'felix'}, {'name':'rex', 'name_xyz' : 'bob'}]"
JObject o = JObject.Parse(json);
https://www.newtonsoft.com/json/help/html/ParseJsonObject.htm
Newtonsoft reference - JObject
https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm
More examples on using JObject as opposed to hard typing
https://www.newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm
I am having trouble understanding when to use JContainer, JObject, and JToken. I understand from the "standards" that JObject is composed of JProperties and that JToken is the base abstract class for all of the JToken types, but I don't understand JContainer.
I am using C# and I just bought LinqPad Pro 5.
I have a JSON data source in a file, so I'm deserializing that file's contents successfully using this statement:
string json;
using (StreamReader reader = new StreamReader(#"myjsonfile.json"))
{
json = reader.ReadToEnd();
}
At that point, I take the JSON string object and deserialize it to a JObject (and this might be my mistake--perhaps I need to make jsonWork a JToken or JContainer?):
JObject jsonWork = (JObject)JsonConvert.DeserializeObject(json);
In my JSON data (the string represented by JSON), I have three objects--the top-level object look similar to this:
{
"Object1" : { ... },
"Object2" : { ... },
"Object3" : { ... }
}
Each object is composed of all sorts of tokens (arrays, strings, other objects, etc.), so it is dynamic JSON. (I used ellipses as placeholders rather than muddying up this question wit lots of JSON data.)
I want to process "Object1", "Object2", and "Object3" separately using LINQ, however. So, ideally, I would like something like this:
// these lines DO NOT work
var jsonObject1 = jsonWork.Children()["Object1"]
var jsonObject2 = jsonWork.Children()["Object2"]
var jsonObject3 = jsonWork.Children()["Object3"]
But the above lines fail.
I used var above because I have no idea what object type I should be using: JContainer, JObject, or JToken! Just so you know what I want to do, once the above jsonObject# variables are properly assigned, I would like to use LINQ to query the JSON they contain. Here is a very simple example:
var query = from p in jsonObject1
where p.Name == "Name1"
select p
Of course, my LINQ ultimately will filter for JSON arrays, objects, strings, etc., in the jsonObject variable. I think once I get going, I can use LinqPad to help me filter the JSON using LINQ.
I discovered that if I use:
// this line WORKS
var jsonObject1 = ((JObject)jsonWork).["Object1"];
Then I get an JObject type in jsonObject1. Is this the correct approach?
It is unclear to me when/why one would use JContainer when it seems that JToken and JObject objects work with LINQ quite well. What is the purpose of JContainer?
You don't really need to worry about JContainer in most cases. It is there to help organize and structure LINQ-to-JSON into well-factored code.
The JToken hierarchy looks like this:
JToken - abstract base class
JContainer - abstract base class of JTokens that can contain other JTokens
JArray - represents a JSON array (contains an ordered list of JTokens)
JObject - represents a JSON object (contains a collection of JProperties)
JProperty - represents a JSON property (a name/JToken pair inside a JObject)
JValue - represents a primitive JSON value (string, number, boolean, null)
So you see, a JObject is a JContainer, which is a JToken.
Here's the basic rule of thumb:
If you know you have an object (denoted by curly braces { and } in JSON), use JObject
If you know you have an array or list (denoted by square brackets [ and ]), use JArray
If you know you have a primitive value, use JValue
If you don't know what kind of token you have, or want to be able to handle any of the above in a general way, use JToken. You can then check its Type property to determine what kind of token it is and cast it appropriately.
JContainer is a base class for JSON elements that have child items. JObject, JArray, JProperty and JConstructor all inherit from it.
For example, the following code:
(JObject)JsonConvert.DeserializeObject("[1, 2, 3]")
Would throw an InvalidCastException, but if you cast it to a JContainer, it would be fine.
Regarding your original question, if you know you have a JSON object at the top level, you can just use:
var jsonWork = JObject.Parse(json);
var jsonObject1 = jsonWork["Object1"];
Most examples have simple json and I've googled "C# Newtonsoft parse JSON" more than once.
Here's a bit of a json file I was just asked to parse for a csv. The company name value is nested within many arrays / objects so it is semi-complicated in that regard.
{
"page": {
"page": 1,
"pageSize": 250
},
"dataRows": [
{
"columnValues": {
"companyName": [
{
"name": "My Awesome Company",
}
]
}
}
]
}
var jsonFilePath = #"C:\data.json";
var jsonStr = File.ReadAllText(jsonFilePath);
// JObject implementation for getting dataRows JArray - in this case I find it simpler and more readable to use a dynamic cast (below)
//JObject jsonObj = JsonConvert.DeserializeObject<JObject>(jsonStr);
//var dataRows = (JArray)jsonObj["dataRows"];
var dataRows = ((dynamic)JsonConvert.DeserializeObject(jsonStr)).dataRows;
var csvLines = new List<string>();
for (var i = 0; i < dataRows.Count; i++)
{
var name = dataRows[i]["columnValues"]["companyName"][0]["name"].ToString();
// dynamic casting implemntation to get name - in this case, using JObject indexing (above) seems easier
//var name2 = ((dynamic)((dynamic)((dynamic)dataRows[i]).columnValues).companyName[0]).name.ToString();
csvLines.Add(name);
}
File.WriteAllLines($#"C:\data_{DateTime.Now.Ticks}.csv", csvLines);
I'm gathering data from a web API which returns a complex JSON string. This contains values of many different types, a few arrays, and some fairly deep nesting.
Currently I'm converting the string to a dynamic object like so:
dynamic dynamicObject = JsonConvert.DeserializeObject(jsonString);
Then I'm retrieving values from this object as needed and typecasting them, however this method gives a null reference exception when I attempt to retrieve an array:
int myValue = (int)dynamicObject.foo.value; // Works!
int[] myArrayOfInts = (int[])dynamicObject.bar.values; // Null
I'm not sure how to proceed as I'm fairly new to C# and ASP.net. Most of the solutions I have come across so far require the creation of small, strictly-typed classes which mirror the entire JSON structure. In my case it would be preferable to simply use a dynamic object, partly for simplicity and partly because only certain values are actually being used.
When I try to run your code, I get a RuntimeBinderException: Cannot convert type 'Newtonsoft.Json.Linq.JArray' to 'int[]'. You can do this conversion with ToObject.
dynamic dynamicObject = JsonConvert.DeserializeObject("{\"values\": [1, 3, 4]}");
int[] myArrayOfInts = dynamicObject.values.ToObject<int[]>();
The cast to int works because a casting conversion is defined for many types including int, but not int[].
You could deserialize the array using the ToObject<type> extension method (where type is the desired data type):
var jsonString = #"{ ""name"":""test"", ""array"": [""10"",""20"",""30"",""40""] }";
dynamic dynamicObject = JsonConvert.DeserializeObject(jsonString);
Console.WriteLine(((string)dynamicObject.name));
var items = dynamicObject.array.ToObject<int[]>();
foreach (var item in items)
{
Console.WriteLine(item);
}
The output is:
test
10
20
30
40
Another possibility would be to cast the object to JObject and then fetch the array as a property - the retrieved object is automatically of type JToken, which allows iteration:
var array = ((JObject)dynamicObject)["array"];
foreach (var item in array)
{
Console.WriteLine(item.ToString());
}