How to access elements of a JArray (or iterate over them)
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
}
How to iterate thorugh JArray items in list
You can use SelectTokens()
to find all service values. SelectTokens()
supports querying of multiple properties nested deep inside JSON objects with wildcards and/or filters using the JSONPath syntax.
var services = stops
.SelectTokens("departures.all[*].service")
.Select(t => (string)t)
.ToList();
Here [*]
is the wildcard operator returning all entries in the departures.all[]
array.
For a full description of JSONPath see here.
Sample fiddle.
JSON iterate over JArray and Add property
string jsonString = "{'name':'company','type':'record','fields':[{'name':'WorkStatus','type':'string'},{'name':'DeploymentCode','type':'string'},{'name':'entity','type':'string'},{'name':'lastUpdatedDate','type':'string'},{'name':'lastUpdatedBy','type':'string'},{'name':'EffectiveDate','type':'string'}]}";
//Note: You must convert to JObject
var jsonObject = JObject.Parse(jsonString);
var jsonFields = jsonObject["fields"];
List<JObject> jsonList = new List<JObject>();
foreach (var item in jsonFields)
{
var tempJson = JObject.Parse(item.ToString());
tempJson.Add("default", "null");
jsonList.Add(tempJson);
}
var getListJson = JToken.FromObject(jsonList);
//Fixed! :)
jsonObject.Remove("fields");
jsonObject.Add("fields", getListJson);
that's it!
How to access the values from a JArray?
Your jArray
is actually a JObject
which contains a JArray
(in the data
property).
Try it like this:
foreach (var item in jArray["data"])
{
emailIDsoe = (string)item["Site_Owner_Email_IDs"];
}
Fiddle: https://dotnetfiddle.net/tzcXql
Iterating through a nested JSON Array in C# with Newtonsoft
A JObject
is an object (analogous to a class):
{
"a": 1,
"b": true
}
A JArray
is a JSON array, and contains multiple JObject
entities:
[
{
"a": 1,
"b": true
},
{
"a": 2,
"b": true
}
]
The root of a JSON document can be an object, or an array. In your case, it's an array.
The following code and fiddle reveals that your code is fine, provided that you deserialize the document as what it is - an array.
string json = "[{\"id\":1,\"name\":\"Section1\",\"project_id\":100,\"configs\":[{\"id\":1000,\"name\":\"myItem1\",\"group_id\":1}]},{\"id\":2,\"name\":\"Section2\",\"project_id\":100,\"configs\":[{\"id\":1001,\"name\":\"myItem2\",\"group_id\":2},{\"id\":1002,\"name\":\"myItem3\",\"group_id\":2},{\"id\":1003,\"name\":\"myItem4\",\"group_id\":2}]},{\"id\":3,\"name\":\"Section3\",\"project_id\":100,\"configs\":[{\"id\":1004,\"name\":\"myItem5\",\"group_id\":5},]}]";
JArray obj = Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(json);
foreach (var result in obj)
{
foreach (JObject config in result["configs"])
{
string id = (string)config["id"];
string name = (string)config["name"];
string gid = (string)config["group_id"];
Console.WriteLine(name + " - " + id + " - " + gid);
}
}
Difference between iterating over JArray and JArray.Children()
There is no difference, you can see the relevant source code here.
The GetEnumerator
method (which would be called by the foreach loop) of JArray
just returns the enumerator of its Children
anyway (around line 327):
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="IEnumerator{T}"/> of <see cref="JToken"/> that can be used to iterate through the collection.
/// </returns>
public IEnumerator<JToken> GetEnumerator()
{
return Children().GetEnumerator();
}
The reason why both ways of iterating over the JArray
exist is because Children
is declared in JToken
, so all its subclasses gotta have it. It also makes sense for JArray
to implement IList<JToken>
, which means that it also implements IEnumerable<JToken>
, allowing you to iterate over it directly with a foreach loop.
Iterate through JSON with Arrays and Objects
Like we talk on the comments,
you need to deserialize your json
private void btnConvert_Click(object sender, EventArgs e)
{
string fileName = "YOUR_PATH\\test.json";
string jsonString = File.ReadAllText(fileName);
Root2 l = JsonConvert.DeserializeObject<Root2>(jsonString);
tbResult.Text = "l.value[1].fields.SystemState.newValue.ToString()- \n" + l.value[1].fields.SystemState.newValue.ToString();
foreach (var item in l.value)
{
if (item.fields.SystemState != null)
{
if (item.fields.SystemState.newValue == "Resolved")
MessageBox.Show("ID - " + item.id);
//ADD HERE THE LOGIC YOU NEED TO UPDATE BY THE ID THE COUNTER
}
}
}
you need to use this classes to create the object l like my example.
public class RevisedBy
{
public string id { get; set; }
public string descriptor { get; set; }
}
public class SystemId
{
public int newValue { get; set; }
}
public class SystemReason
{
public string newValue { get; set; }
}
public class SystemCreatedDate
{
public DateTime newValue { get; set; }
}
public class SystemChangedDate
{
public DateTime newValue { get; set; }
}
public class SystemRev
{
public int oldValue { get; set; }
public int newValue { get; set; }
}
public class SystemState
{
public string oldValue { get; set; }
public string newValue { get; set; }
}
public class Fields
{
[JsonProperty("System.Id")]
public SystemId SystemId { get; set; }
[JsonProperty("System.Reason")]
public SystemReason SystemReason { get; set; }
[JsonProperty("System.CreatedDate")]
public SystemCreatedDate SystemCreatedDate { get; set; }
[JsonProperty("System.ChangedDate")]
public SystemChangedDate SystemChangedDate { get; set; }
[JsonProperty("System.Rev")]
public SystemRev SystemRev { get; set; }
[JsonProperty("System.State")]
public SystemState SystemState { get; set; }
}
public class Value
{
public int id { get; set; }
public int workItemId { get; set; }
public int rev { get; set; }
public RevisedBy revisedBy { get; set; }
public DateTime revisedDate { get; set; }
public Fields fields { get; set; }
}
public class Root2
{
public int count { get; set; }
public List<Value> value { get; set; }
}
and the result:
Newtonsoft json access array inside json
JArray jsonArray = (JArray)o["array"];
string[] stringArray = jsonArray.ToObject<string[]>();
- The indexer operator of
JObject
returns aJToken
which needs to be converted toJArray
- You can call the
ToObject
on it where you can specify the return type as string array
UPDATE #1
Well, you don't need to explicitly cast JToken
to JArray
, since the ToObject
is defined on the JToken
. So the following code would be enough:
var stringArray = o["array"].ToObject<string[]>();
Related Topics
Button in a Column, Getting the Row from Which It Came on the Click Event Handler
Can a Tcp C# Client Receive and Send Continuously/Consecutively Without Sleep
Setting a Webrequest's Body Data
Split a String That Has White Spaces, Unless They Are Enclosed Within "Quotes"
How to Use Transactionscope in C#
Delete a Single Record from Entity Framework
Invalid Cast from 'System.Int32' to 'System.Nullable'1[[System.Int32, Mscorlib]]
How to Find the Current Executable Filename
Dynamic Button Creation & Placing Them in a Predefined Order Using C#
How to Make Backgroundworker Return an Object
What Is C# Analog of C++ Std::Pair
Is Idisposable.Dispose() Called Automatically
How to Delete a File After Checking Whether It Exists
String.Empty Converted to Null When Passing JSON Object to MVC Controller
JSON.Net (De)Serialize Untyped Property
Execute Unit Tests Serially (Rather Than in Parallel)