How to access elements of a JArray (or iterate over them) - c#

I have the following Json gotten from Twitter
+ token {[
{
"trends": [
{
"name": "Croke Park II",
"url": "http://twitter.com/search?q=%22Croke+Park+II%22",
"promoted_content": null,
"query": "%22Croke+Park+II%22",
"events": null
},
{
"name": "#twiznight",
"url": "http://twitter.com/search?q=%23twiznight",
"promoted_content": null,
"query": "%23twiznight",
"events": null
},
{
"name": "#Phanhattan",
"url": "http://twitter.com/search?q=%23Phanhattan",
"promoted_content": null,
"query": "%23Phanhattan",
"events": null
},
{
"name": "#VinB",
"url": "http://twitter.com/search?q=%23VinB",
"promoted_content": null,
"query": "%23VinB",
"events": null
},
{
"name": "#Boston",
"url": "http://twitter.com/search?q=%23Boston",
"promoted_content": null,
"query": "%23Boston",
"events": null
},
{
"name": "#rtept",
"url": "http://twitter.com/search?q=%23rtept",
"promoted_content": null,
"query": "%23rtept",
"events": null
},
{
"name": "Facebook",
"url": "http://twitter.com/search?q=Facebook",
"promoted_content": null,
"query": "Facebook",
"events": null
},
{
"name": "Ireland",
"url": "http://twitter.com/search?q=Ireland",
"promoted_content": null,
"query": "Ireland",
"events": null
},
{
"name": "Everton",
"url": "http://twitter.com/search?q=Everton",
"promoted_content": null,
"query": "Everton",
"events": null
},
{
"name": "Twitter",
"url": "http://twitter.com/search?q=Twitter",
"promoted_content": null,
"query": "Twitter",
"events": null
}
],
"as_of": "2013-04-17T13:05:30Z",
"created_at": "2013-04-17T12:51:41Z",
"locations": [
{
"name": "Dublin",
"woeid": 560743
}
]
}
]} Newtonsoft.Json.Linq.JToken {Newtonsoft.Json.Linq.JArray}
Problem is I can't seem to access any of the elements. I have tried foreach loops and normal for loops and can never seem to access individual elemets it always ends up accessing the whole area.
Any idea how I access the individual elements in this Json JArray?

There is a much simpler solution for that.
Just treat the items of the JArray as JObject.
Let's say we have such array of JSON objects:
JArray jArray = JArray.Parse(#"[
{
""name"": ""Croke Park II"",
""url"": ""http://twitter.com/search?q=%22Croke+Park+II%22"",
""promoted_content"": null,
""query"": ""%22Croke+Park+II%22"",
""events"": null
},
{
""name"": ""Siptu"",
""url"": ""http://twitter.com/search?q=Siptu"",
""promoted_content"": null,
""query"": ""Siptu"",
""events"": null
}]");
To get access each item just do the following:
foreach (JObject item in jArray) // <-- Note that here we used JObject instead of usual JProperty
{
string name = item.GetValue("name").ToString();
string url = item.GetValue("url").ToString();
// ...
}

Update - I verified the below works. Maybe the creation of your JArray isn't quite right.
[TestMethod]
public void TestJson()
{
var jsonString = #"{""trends"": [
{
""name"": ""Croke Park II"",
""url"": ""http://twitter.com/search?q=%22Croke+Park+II%22"",
""promoted_content"": null,
""query"": ""%22Croke+Park+II%22"",
""events"": null
},
{
""name"": ""Siptu"",
""url"": ""http://twitter.com/search?q=Siptu"",
""promoted_content"": null,
""query"": ""Siptu"",
""events"": null
},
{
""name"": ""#HNCJ"",
""url"": ""http://twitter.com/search?q=%23HNCJ"",
""promoted_content"": null,
""query"": ""%23HNCJ"",
""events"": null
},
{
""name"": ""Boston"",
""url"": ""http://twitter.com/search?q=Boston"",
""promoted_content"": null,
""query"": ""Boston"",
""events"": null
},
{
""name"": ""#prayforboston"",
""url"": ""http://twitter.com/search?q=%23prayforboston"",
""promoted_content"": null,
""query"": ""%23prayforboston"",
""events"": null
},
{
""name"": ""#TheMrsCarterShow"",
""url"": ""http://twitter.com/search?q=%23TheMrsCarterShow"",
""promoted_content"": null,
""query"": ""%23TheMrsCarterShow"",
""events"": null
},
{
""name"": ""#Raw"",
""url"": ""http://twitter.com/search?q=%23Raw"",
""promoted_content"": null,
""query"": ""%23Raw"",
""events"": null
},
{
""name"": ""Iran"",
""url"": ""http://twitter.com/search?q=Iran"",
""promoted_content"": null,
""query"": ""Iran"",
""events"": null
},
{
""name"": ""#gaa"",
""url"": ""http://twitter.com/search?q=%23gaa"",
""promoted_content"": null,
""query"": ""gaa"",
""events"": null
},
{
""name"": ""Facebook"",
""url"": ""http://twitter.com/search?q=Facebook"",
""promoted_content"": null,
""query"": ""Facebook"",
""events"": null
}]}";
var twitterObject = JToken.Parse(jsonString);
var trendsArray = twitterObject.Children<JProperty>().FirstOrDefault(x => x.Name == "trends").Value;
foreach (var item in trendsArray.Children())
{
var itemProperties = item.Children<JProperty>();
//you could do a foreach or a linq here depending on what you need to do exactly with the value
var myElement = itemProperties.FirstOrDefault(x => x.Name == "url");
var myElementValue = myElement.Value; ////This is a JValue type
}
}
So call Children on your JArray to get each JObject in JArray. Call Children on each JObject to access the objects properties.
foreach(var item in yourJArray.Children())
{
var itemProperties = item.Children<JProperty>();
//you could do a foreach or a linq here depending on what you need to do exactly with the value
var myElement = itemProperties.FirstOrDefault(x => x.Name == "url");
var myElementValue = myElement.Value; ////This is a JValue type
}

Once you have a JArray you can treat it just like any other Enumerable object,
and using linq you can access them, check them, verify them, and select them.
var str = #"[1, 2, 3]";
var jArray = JArray.Parse(str);
Console.WriteLine(String.Join("-", jArray.Where(i => (int)i > 1).Select(i => i.ToString())));

void ConvertToJArray(object headers)
{
//where headers is your Twitter response
JObject JObj = (JObject)headers;//Parse to JObject
JArray JArr = (JArray)JObj["trends"];//Get the trends array as JArray
for (int i = 0; i < JArr.Count; i++)
{
var Name = JArr[i]["name"].ToString();
var URL = JArr[i]["url"].ToString();
}
}

Related

Filter data from deep json child

the JSON below is taken from other post. My issue is I know the id and I want to find out where is it located. Eg, I got ID 19006 and I want to get Folder2. How am I going to do this.
{
"data": {
"id": 0,
"name": "",
"childFolders": [{
"id": 19002,
"name": "Locker",
"childFolders": [{
"id": 19003,
"name": "Folder1",
"childFolders": [],
"childComponents": [{
"id": 19005,
"name": "route1",
"state": "STOPPED",
"type": "ROUTE"
}]
}, {
"id": 19004,
"name": "Folder2",
"childFolders": [],
"childComponents": [{
"id": 19008,
"name": "comm1",
"state": "STOPPED",
"type": "COMMUNICATION_POINT"
}, {
"id": 19006,
"name": "route2",
"state": "STOPPED",
"type": "ROUTE"
}, {
"id": 19007,
"name": "route3",
"state": "STOPPED",
"type": "ROUTE"
}]
}],
"childComponents": []
}],
"childComponents": []
},
"error": null
}
I write code now it is like this:
var json = GetJsonString();
var model = GetJsonModel(json);
var folderName = GetName(model.data, 19006);
I chekced and code is correct. folderName is Folder2
And the recursive code:
private string GetName(Data data, int searchValue)
{
var folderName = data.name;
foreach (var item in data.childComponents)
{
if (item.id == searchValue)
{
return folderName;
}
}
if (data.childFolders.Length > 0)
{
foreach (var item in data.childFolders)
{
var folderName1 = GetName(item, searchValue);
if (folderName1 != null)
{
return folderName1;
}
}
}
return null;
}
Your model is like this:
EDIT:
I parse Json like this.
return JsonSerializer.Deserialize<YourJson>(test);

Match and Map fields from two lists LINQ

I have two separate API requests.
The first one gives me a JSON List of Mailshake campaigns.
var requestCampaings = new RestRequest("/2017-04-01/contolerr/method", Method.GET);
In turn, I get this response.
{
"nextToken": "1545314518|240060",
"results": [
{
"object": "campaign",
"id": 36,
"title": "Email Part 2",
"created": "2019-08-12T11:50:01.442Z",
"archived": null,
"isPaused": false,
"messages": [
{
"object": "message",
"id": 7764,
"type": "initial",
"subject": "chat",
"replyToID": null,
"isPaused": false
}
],
"sender": {
"object": "sender",
"id": "359-false",
"emailAddress": "sxxxxxxxxxt#xxxxx.com",
"fromName": "xxxxxx xxxxx",
"created": "2019-05-13T14:53:49.615Z"
},
"url": "https://mailshake.com/app/#/17032/cont/360213/overview"
},
{
"object": "campaign",
"id": 359073,
"title": "TEST xxxxxx",
"created": "2019-08-09T09:16:42.286Z",
"archived": null,
"isPaused": false,
"messages": [
{
"object": "message",
"id": 774276,
"type": "initial",
"subject": "Test Test",
"replyToID": null,
"isPaused": false
}
],
"sender": {
"object": "sender",
"id": "24121-28668-false",
"emailAddress": "xxxxxxxxx#xxxxxx.xx.xx",
"fromName": "xxxxx xxxxxx",
"created": "2018-09-24T11:53:48.961Z"
},
"url": "https://mailshake.com/app/#/1/campaigns/73/overview"
},
{
"object": "xxxxx",
"id": 35,
"title": " Outreach",
"created": "2019-08-08T16:34:23.76Z",
"archived": null,
"isPaused": true,
"messages": [],
"sender": {
"object": "sender",
"id": "24121-28668-false",
"emailAddress": "xxxxx#xxxx.xx.xxx",
"fromName": "xxxxx xxxx",
"created": "2018-09-24T11:53:48.961Z"
},
"url": "https://mailshake.com/app/#/172/campaigns/3/overview"
},...
}
I store this response in OpenResponseViewModel
var campaings = JsonConvert.DeserializeObject<OpensResponseViewModel>(contentCampaings).Results;
then I filter it out into Response Model as an element in list for every campaign.
var campaingsIds = campaings.Select(a => new Response() { CampaignId = a.Id, SenderEmail = a.Sender.EmailAddress }).ToList();
Simular for the second call to the API I get all open emails as JSON.
var info = JsonConvert.DeserializeObject(contentOpens).Results;
var emailClicked = info.Where(x=>x.IsDuplicate==false).Select(a => new Response() { CampaignId = a.Campaign.Id, RecipientIEmail = a.Recipient.EmailAddress }).ToList();
So basically I get two lists of objects.
CampaingId: 360213
RecipientEmailAddress : null
SenderEmailAddress : sender360213#mail.com
CampaingId: 358593
RecipientEmailAddress : null
SenderEmailAddress : sender358593#mail.com
and
CampaingId: 358593
RecipientEmailAddress : recipient#mail.com
SenderEmailAddress : null
CampaingId: 360213
RecipientEmailAddress : recipient#mail.com
SenderEmailAddress : null
What I need is match the CampaingId from the first list to the CampaingId from the second list into 3rd list to get the SenderEmailAddress.
and get a list of objects like this
CampaingId: 358593
RecipientEmailAddress : recipient#mail.com
SenderEmailAddress : sender358593#mail.com
CampaingId: 360213
RecipientEmailAddress : recipient#mail.com
SenderEmailAddress : sender360213#mail.com
how do i do this witl LINQ
Join the lists:
var q = from c in campaingsIds
join e in emailClicked on c.CampaingId equals e.CampaingId
select new Response()
{
CampaingId = c.CampaingId,
RecipientEmailAddress = e.RecipientEmailAddress,
SenderEmailAddress = c.SenderEmailAddress
};

Searching for fields in a Json file in C#

I have a Json file with couple of fields and I have some problems searching for specific fields.
This is the Json file(I cut it short since the original is huge):
{
"errors": {
"errorCode": 0,
"errorMessage": "",
"errorDescription": null
},
"pagination": {
"recordsReturned": 250,
"totalRecordsFound": 123,
"currentPage": 1,
"recordsPerPage": 250
},
"data": {
"totalDCount": 1713,
"totalValue": "50",
"totalCarats": 60,
"averagePricePerCarat": 21,
"averageDiscount": -0.29,
"dResult": [
{
"color": "H",
"dID": 4693,
"fancyColor": {
"dominantColor": null,
"secondaryColor": null,
"overtones": null,
"intensity": null,
"color1": null,
"color2": null
},
"seller": {
"accountID": 124,
"companyName": "",
"companyCode": " ",
"founded": "",
"address": null,
"telephone": " ",
"fax": null,
"email": null,
"contactPrimaryName": "value",
"city": null,
"state": null,
"country": "USA",
"address1": null,
"address2": null,
"skypeName": null,
"primarySupplierBadge": true,
"ratingPercent": 1.0,
"totalRating": 1.0,
"relatedAccounts": null
},
"shape": "Round",
{
"color": "H",
"dID": 46,
"fancyColor": {
"dominantColor": null,
"secondaryColor": null,
"overtones": null,
"intensity": null,
"color1": null,
"color2": null
},
"seller": {
"accountID": 124,
"companyName": "",
"companyCode": " ",
"founded": "",
"address": null,
"telephone": " ",
"fax": null,
"email": null,
"contactPrimaryName": "value",
"city": null,
"state": null,
"country": "USA",
"address1": null,
"address2": null,
"skypeName": null,
"primarySupplierBadge": true,
"ratingPercent": 1.0,
"totalRating": 1.0,
"relatedAccounts": null
},
"shape": "Round"
}
]
}
}
I wrote a code that should search for "dId" field value under the "dResult". Unfortunately this error comes up (I am using Newtonsoft.Json parser) :
"Newtonsoft.Json.JsonReaderException: Invalid property identifier character: {. Path 'data.dResult[0].shape', line 54, position 11."
A.This is the code I wrote, I would be happy if you could tell me what is the problem ?
B.A second problem that I had is that I need to pick only the "dID" of those that have the "shape" field value as "Round", I didn't figure out a way to do that since I need to go and find a further field while encountering "dId" field .
class Program
{
static void Main(string[] args)
{
string filepath = "../../json1.json";
string result = string.Empty;
string str = string.Empty;
using (StreamReader r = new StreamReader(filepath))
{
var json = r.ReadToEnd();
JObject jObject = JObject.Parse(json);
JToken jUser = jObject["data"];
string jsonString = jUser.ToString();
JObject jObject1 = JObject.Parse(jsonString);
JToken jUser2 = jObject1["dResult"];
string jsonString2 = jUser2.ToString();
JObject jObject2 = JObject.Parse(jsonString2);
foreach (var item in jObject2.Properties())
{
if (item.Name == "dID")
{
str = item.Value.ToString();
result = result + " " + str;
}
}
}
Console.WriteLine(result);
}
}
Reference for the comment I received here (Another Json section, this is under "dResult"):
, {
"dID": 281242,
"seller": {
"accountID": 21321,
"companyName": "RA",
"companyCode": "001",
"founded": "000",
"address": null,
"telephone": "999",
"fax": null,
"email": null,
"contactPrimaryName": "name",
"city": null,
"state": null,
"country": "USA",
"address1": null,
"address2": null,
"skypeName": null,
"primarySupplierBadge": true,
"ratingPercent": 1.0,
"totalRating": 1.0,
"relatedAccounts": null
},
"shape": "Round",
"size": 0.010,
"color": "K",
"fancyColor": {
"dominantColor": null,
"secondaryColor": null,
"overtones": null,
"intensity": null,
"color1": null,
"color2": null
},
You can use the following Linq query to pull the dID values for the Round shapes. However the JSON is not in a correct format.
var jsonStr = File.ReadAllText(Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
"example-json.json"));
var parsed = JObject.Parse(jsonStr);
var dIdList = parsed["data"]["dResult"]
.Where(x => x.Value<String>("shape").Equals("round", StringComparison.InvariantCultureIgnoreCase))
.Select(x => x.Value<Int32>("dID"))
.ToList();
And here is the re-formatted JSON (notice the diff on line 52-53), there was a missing } which caused the array to be off:
Once you correct the JSON, by adding this } and run the above Linq query it will return the following result:
Good, luck. Let me know if you need any further assistance.
Once you fix the improperly formatted json data, you can use linq to find the round objects:
var searchResults = from r in jObject["data"]["dResult"]
where r["shape"].ToString() == "Round"
select r;
foreach (var r in searchResults)
{
Console.WriteLine(r["dID"]);
}

How to safely deserialize keys/data format JSON response

I am getting this 'optimized' JSON response from a third party web service presented as follows, I built the type as per the information presented in the keys but the difficulty I am facing is that data is not represented in objects but in arrays, is there a way to automate the building and value mapping of my objects list?
{
"reports": {
"query": {
"keys": [{
"name": "Date",
"type": "date"
}, {
"name": "NetSales",
"type": "price"
}, {
"name": "GrossCash",
"type": "price"
}, {
"name": "GrossCard",
"type": "price"
}, {
"name": "GrossDelivery",
"type": "price"
}, {
"name": "NetFood",
"type": "price"
}, {
"name": "NetDrink",
"type": "price"
}, {
"name": "NetRetail",
"type": "price"
}, {
"name": "Baskets",
"type": "int"
}],
"data": [
[1523577600000, 51924, 11300, 27200, 9900, null, null, null, 8],
[1523404800000, 7434, 2600, 3900, null, null, null, null, 6],
[1523491200000, 18101, 4000, 10100, null, null, null, null, 5],
[1523664000000, 13243, 7400, 6500, null, null, null, null, 3],
[1523750400000, 11718, 7300, null, 5000, null, null, null, 2],
[1523836800000, 16576, 7700, 4800, 4900, null, null, null, 4],
[1524096000000, 20293, 9100, 6000, null, null, null, null, 4]
]
}
},
"api": {
"message": {
"success": {
"202": {
"id": 202,
"title": "Token is valid",
"details": "Token is validated and found valid."
}
}
},
"codeBaseVersion": 1,
"executionTime_milliSeconds": 43
}
}
I ended up with this code but not satisfied with it:
JObject myOpject = JObject.Parse(responseString);
List<JToken> setOfObjects = myOpject["reports"]["query"]["data"].Children().ToList();
var listOfData = new List<Data2>();
foreach (var token in setOfObjects)
{
var myObject = new Data2
{
NetSales = decimal.Parse(token[1].ToString()),
//etc.
};
listOfData.Add(myObject);
}
using the same JToken idea transform the data using the keys to create a new object model and then deserialize that to the strong type desired.
For example, taking a few records you can transform the keys and data to
[
{
"Date": 1523577600000,
"NetSales": 51924,
...
},
{
"Date": 1523404800000,
"NetSales": 7434,
...
},
...
]
The following code attempts to build that using the key index matched to the index of item in data array
JObject myOpject = JObject.Parse(responseString);
List<JToken> keys = myOpject["reports"]["query"]["keys"].Children().ToList();
List<JToken> data = myOpject["reports"]["query"]["data"].Children().ToList();
var array = new JArray();
foreach (var token in data) {
var record = new JObject();
for (var i = 0; i < keys.Count; i++) {
var propertyName = keys[i]["name"].Value<string>();
var propertyValue = token[i];
record[propertyName] = propertyValue;
}
array.Add(record);
}
var listOfData = array.ToObject<List<Data2>>(); // or Data2[], etc
assuming Data2 is your strongly typed model with matching properties.

Deserialize GET response

How do I deserialize this text. I tried with JSON but I get "Invalid JSON primitive" error.
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 1
},
"objects": [
{
"blocked": false,
"groups": [],
"id": "1111",
"name": "John Doe",
"number": "+15555555555",
"resource_uri": "/api/v1/contacts/1111/"
}
]
}
This is the code I used:
var jss = new JavaScriptSerializer();
var dictionary = jss.Deserialize<Dictionary<string, string>>(buffer.ToString());
Easy to Fix. Deserialize to <Dictionary<string, object> instead of <Dictionary<string, string>
var dictionary = jss.Deserialize<Dictionary<string, object>>(buffer.ToString());
Full test code
string json = #"{
""meta"": {
""limit"": 20,
""next"": null,
""offset"": 0,
""previous"": null,
""total_count"": 1
},
""objects"": [
{
""blocked"": false,
""groups"": [],
""id"": ""1111"",
""name"": ""John Doe"",
""number"": ""+15555555555"",
""resource_uri"": ""/api/v1/contacts/1111/""
}
]
}";
var jss = new JavaScriptSerializer();
var dictionary = jss.Deserialize<Dictionary<string, object>>(json);

Categories