Json nested parameters - c#

I am using data from a Json object to populate a list view. The object has these parameters:
"id": "339150749455906",
"posts": {
"data": [
{
"id": "339150749455906_545370565500589",
"from": {
"category": "Food/beverages",
"name": "Pepsi",
"id": "339150749455906"
},
"story": "Pepsi updated their cover photo.",
"picture": "http://photos-g.ak.fbcdn.net/hphotos-ak-ash3/942740_545370555500590_46289134_s.jpg",
"link": "http://www.facebook.com/photo.php?fbid=545370555500590&set=a.365573920146922.72816.339150749455906&type=1&relevant_count=1",
"icon": "http://static.ak.fbcdn.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif",
"actions": [
{
"name": "Comment",
"link": "http://www.facebook.com/339150749455906/posts/545370565500589"
},
{
"name": "Like",
"link": "http://www.facebook.com/339150749455906/posts/545370565500589"
}
],
I want to access the link inside the parameter/key "actions". So far I am using:
foreach (var post in postsTaskResult.posts.data)
{
link = new Uri(string.Format("{0}", (string)post["link"]));
}
However, this only brings the link in the "data". How can I access the other 'link' ?

Try this.
var actionLinks = new List<string>();
var actions = post["actions"] as JArray; // if this works then all is well
foreach(var item in actions)
{
actionLinks.Add((string)item["link"]);
}
I think you can also use some fancy Linq with this like
var actionLinks = ((JArray)post["actions"])
.Children<JObject>()
.Select(a => (string)a["link"])
.ToList();
Very un-tested. Just let me know.

Related

How to extract specific value from this json string using linq

could anyone help me extract the specific value for [downloads][csv][href] out of the following json string please?
{
"#context": "https://cdn.ons.gov.uk/assets/json-ld/context.json",
"alerts": [],
"collection_id": "cmdr",
"dimensions": [
various dimensions here
],
"downloads": {
"csv": {
"href": "https://download.beta.ons.gov.uk/downloads/datasets/regional-gdp-by-year/editions/time-series/versions/4.csv",
"size": "568021"
},
"csvw": {
"href": "ref",
"size": "1903"
},
"xls": {
"href": "ref",
"size": "80768"
}
},
"edition": "time-series",
"id": "5c",
"links": {
"dataset": {
"href": "ref",
"id": "regional-gdp-by-year"
},
"edition": {
"href": "ref",
"id": "time-series"
},
"self": {
"href": "ref"
}
},
"release_date": "2021",
"state": "published",
"usage_notes": [],
"version": 4
}
the current code I am using returns nothing:
var labels = JObject.Parse(observationsJson)["downloads"];
var results = labels.Select(data => new
{
label = (string)data["href"]
});
foreach (var item in results)
{
csvDownloadAddress = item.label;
}
If there is another method rather than using linq then I am open to suggestions.
Sorry if this is a dumb quest, my experience with linq and json is very limited.
thank you for your help.
You have JSON Path, that can be used to select specific element(s) from the JSON string.
see Newtonsoft example, or you can use this JsonPath Nuget package.
The JsonPath Nuget can be used like below,
var input = "$.downloads.csv.href";
var path = JsonPath.Parse(input);
var hrefVal = path.Evaluate(jsonStr);

Filtering or removing array objects from the DTO class object based on an another list in .net

I have below code :
[
{
"OrderId": "Order1",
"filterOrder": [ "ABC", "XYZ" ],
"Details": [
{
"id": 1,
"value": 100,
"filterDetails": [ "Apples", "Oranges" ]
},
{
"id": 2,
"value": 200,
"filterDetails": [ "Banana", "Blank" ]
}
]
},
{
"OrderId": "Order2",
"filterOrder": [ "PQR", "Blank" ],
"Details": [
{
"id": 1,
"value": 100,
"filterDetails": [ "Apples", "Peaches" ]
},
{
"id": 2,
"value": 200,
"filterDetails": [ "Banana", "Mango" ]
}
]
}
]
C# code:
string i = GetJsonText();
var lst = JsonConvert.DeserializeObject<List<Root>>(i);
My requirement here is to remove all those objects from the response where the filters are mentioned as "Blank".
So I have used the below code to remove the blanks :
lst.RemoveAll(x => x.filterOrder.Contains("Blank"));
lst.ForEach(fe => {fe.Details.RemoveAll(r=> r.filterDetails.Contains("Blank"));});
This is working perfectly fine. But now the requirement changed to remove objects based on multiple strings and not single string. Means I'll have something like
string removeCriteria ="Blank,Blank1,Blank2"
I convert this into a list of strings like this :
List<String> removeList = removeCriteria.Split(",").ToList();
Now I have use removeList in the above code instead of hardcoded "Blank". What can I try to resolve this?
No sure if I am missing something here but isn't this a fairly simple ForEeach loop?
string removeCriteria ="Blank,Blank1,Blank2"
List<String> removeList = removeCriteria.Split(",").ToList();
ForEach (String toRemove in removeList)
{
lst.RemoveAll(x => x.filterOrder.Contains(toRemove));
lst.ForEach(fe => {fe.Details.RemoveAll(r=>r.filterDetails.Contains(toRemove));});
}
For a little better performance, especialy if each parent has alot of child records, I would suggest to change MattBaran answer a little
string removeCriteria ="Blank,Blank1,Blank2"
List<String> removeList = removeCriteria.Split(",").ToList();
//at first remove all parents with children
foreach (var toRemove in removeList)
{
lst.RemoveAll(x => x.filterOrder.Contains(toRemove));
}
//after this check the children of remaining records
foreach (var toRemove in removeList)
{
lst.ForEach(fe => {fe.Details.RemoveAll (r=>r.filterDetails.Contains (toRemove));});
}

Transform a JSON object to a JSON array, taking the first level of properties

I've this JSON object
{
"08f4f705-6e14-4781-8241-d04bf2dc6ada": {
"description": "xxxxxxxx",
"note": "yyyyyyyy"
},
"05f4f995-6e14-4567-8241-d04bf2d456ee": {
"description": "aaaaaa",
"note": "bbb"
},
"0675f995-6e14-4567-8241-d4567f2d456z": {
"description": "fffff",
"note": "gggg"
}
}
I need to convert into a JSON array like this:
(the elements should be the content of the first level properties)
[
{
"description": "xxxxxxxx",
"note": "yyyyyyyy"
},
{
"description": "aaaaaa",
"note": "bbb"
},
{
"description": "fffff",
"note": "gggg"
}
]
I can't manipulate the object and I didn't find an appropriate resource to follow. How can I do it?
You can achieve this by deserializing your json string into Dictionary<string, object>:
var obj = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
After that you extract the values and serialize them back to json:
var newJson = JsonConvert.SerializeObject(obj.Values);

Deserialize Dynamic Json string using Newtonsoft JSON.NET

I have a JSON string that I'm getting from Facebook API, in which I have a node whose name changes according to its content, for example some time it is 45, or 58 etc.
It could be any number.
I want its value. How to get it?
Example:
{
"data": [
{
"id": "1492292372_10201810786059989",
"created_time": "2014-04-05T09:00:54+0000"
},
{
"id": "1492292372_10201804679827337",
"created_time": "2014-04-04T07:29:07+0000"
},
{
"id": "1492292372_10201804649306574",
"created_time": "2014-04-04T07:10:33+0000"
},
{
"id": "1492292372_10201801316823264",
"created_time": "2014-04-03T18:31:50+0000"
},
{
"id": "1492292372_10201798962284402",
"created_time": "2014-04-03T06:24:47+0000"
},
{
"message_tags": {
"0": [
{
"id": "1492292372",
"name": "Yawar Sohail",
"type": "user",
"offset": 0,
"length": 12
}
],
"15": [
{
"id": "1489845168",
"name": "Zeeshan Anjum",
"type": "user",
"offset": 15,
"length": 13
}
]
},
"id": "1492292372_10201796274777216",
"created_time": "2014-04-02T17:57:05+0000"
},
{
"id": "1492292372_10201794080482360",
"created_time": "2014-04-02T07:26:23+0000"
},
Inside message_tags there are two nodes [0 and 15] they dynamically changes according to their offset values. I want names, type and ids inside these nodes.
You can deserialize your JSON into an ExpandoObject:
var converter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json, converter);
Which dynamically adds members to your object at runtime, and allows you to iterate over them as described in this answer:
foreach (var prop in obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
Console.WriteLine("Name: {0}, Value: {1}",prop.Name, prop.GetValue(obj,null));
}
That way you can iterate over obj.message_tags to get the individual messages, and obtain all their details respectively.

JSON nested array

Lets say i have the following JSON
{
"data": [
{
"from": {
"name": "aaa bbb",
},
"actions": [
{
"name": "Comment",
"link": "http://...
},
{
"name": "Like",
"link": "http://.."
}
],
},
And i have
JSONObject wallData = helper.Get("/me/feed");
if (wallData != null)
{
var data = wallData.Dictionary["data"];
List<JSONObject> wallPosts = data.Array.ToList<JSONObject>();
}
foreach (Facebook.JSONObject wallItem in wallPosts)
{ ... }
Which stores me whole feed into wallData and 'data' object into wallPosts.
So then i can access the wallItem.Dictionary["from"].Dictionary["name"], and i get "aaa bbb".
But i can't get inside the actions array
The wallItem.Dictionary["actions"].Dictionary["name"] doesn't work.
Any idea
You need to do something like wallItem.Dictionary["actions"][0].Dictionary["name"] because "actions" is an array.
On a different note...its neater if u directly into a class...like this
var jSerializer = new JavaScriptSerializer();
var jsonObject = jSerializer.Deserialize<DataObject>(json);
The DataObject will be a class which emulates ur JSON data in a strongly typed class. Depending on the size of ur Json you will not have to use a lot of strings in your code.

Categories

Resources