How to get value of JArray dictionary by key - c#

I have this json string:
[
[
{
"Antibiotic after diagnosis":[
"Azithromycin",
"Ciprofloxacin HCl",
"Ampicillin Sodium"
],
"City":[
"Tel Aviv",
"Jerusalem"
]
}
],
[
{
"Antibiotic after diagnosis":"Azithromycin",
"City":"Tel Aviv"
},
{
"Antibiotic after diagnosis":"Ciprofloxacin HCl",
"City":"Jerusalem"
}
]
]
I deserialized this string:
data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<object>>("*json str*");
JParameters = data[0] as JArray;
Debug.Log(JParameters["Antibiotic after diagnosis"]);
But when i run the code it crashed on the line (Debug.Log(JParameters["Antibiotic after diagnosis"]);) with the following error:
"ArgumentException: Accessed JArray values with invalid key value: "Antibiotic after diagnosis". Int32 array index expected."

The index into JParameters should be an integer as the error states. What you want is:
JParameters[0]["Antibiotic after diagnosis"]
The above code selects the first element, and then selects the value for the dictionary key "Antibiotic after diagnosis".
I recommend reading w3schools JSON to properly understand how JSON works.

One option is to get key, value from Jproperty.
var files = JArray.Parse(YourJSON);
foreach (JArray item in files.Children())
{
foreach (JObject obj in item.Children())
{
foreach (JProperty prop in obj.Children())
{
string key = prop.Name.ToString();
string value = prop.Value.ToString();
}
}
}

Related

How to remove a key value pair within a nested json structure in C#

I have the following json
{
"audit_date": "2020-05-13T11:27:10.3187798Z",
"client_uuid": "2fd77dd8-ed76-4bba-b0e1-5cda454c8d6e",
"audit_entry": {
"where_uri": "test.com/dataservice/apps/171f0841-825b-4964-8f8c-0869650f14a6",
"why_uri": "test.com/dataservice/reference/reasons_for_change/61acc173-7168-4ae5-9f04- afa228941f8b",
"who_uri": "test.com/securityservice/users/4977dae1-a307-425f-980c-53413fef1b0f",
"when_audited": "2018-11-13T20:20:39+00:00",
"what_uri": "test.com/dataservice/study_subjects/1bc67a71-8549-4ab8-9dd9-e44238198860",
"what_changed": [
{
"attribute_name": "birth_year",
"attribute_value": "1969",
"attribute_change": "1970"
},
{
"attribute_name": "subject_reference",
"attribute_value": "TEST-WOO3444",
"attribute_change": null
}
]
}
}
And I want to remove the second attribute_change key value pair to be as follows
{
"audit_date": "2020-05-13T11:27:10.3187798Z",
"client_uuid": "2fd77dd8-ed76-4bba-b0e1-5cda454c8d6e",
"audit_entry": {
"where_uri": "test.com/dataservice/apps/171f0841-825b-4964-8f8c-0869650f14a6",
"why_uri": "test.com/dataservice/reference/reasons_for_change/61acc173-7168-4ae5-9f04- afa228941f8b",
"who_uri": "test.com/securityservice/users/4977dae1-a307-425f-980c-53413fef1b0f",
"when_audited": "2018-11-13T20:20:39+00:00",
"what_uri": "test.com/dataservice/study_subjects/1bc67a71-8549-4ab8-9dd9-e44238198860",
"what_changed": [
{
"attribute_name": "birth_year",
"attribute_value": "1969",
"attribute_change": "1970"
},
{
"attribute_name": "subject_reference",
"attribute_value": "TEST-WOO3444",
}
]
}
}
I have tried the following code
JObject jObject = JObject.Parse(jsonText);
JObject jObj = (JObject)jObject.SelectToken("audit_entry");
//remove second attribute changed token
jObj.Property("what_changed")("attribute_change")[1].Remove();
string json = jObj.ToString(Formatting.None);
I know the syntax is wrong for jObj.Property but after a few hours of googling I cannot find the answer.
Any help much appreciated.
You can remove a property from JObject by calling Remove method with corresponding property name. For example:
JObject jObject = JObject.Parse(jsonText);
// find required object, there are other options
// for example (JObject)jObject["audit_entry"]["what_changed"][1]
var nested = (JObject)jObject.SelectToken("$.audit_entry.what_changed[1]");
//remove attribute changed token
nested.Remove("attribute_change");
string json = jObject.ToString(Formatting.None); // attribute_change is removed from jObject
If you want to remove all properties with such name and null for value you can do next:
var toRemove = jObject.Descendants()
.OfType<JProperty>()
.Where(prop => prop.Name == "attribute_change" && prop.Value.Type == JTokenType.Null)
.ToList();
foreach (var prop in toRemove)
{
prop.Remove();
}
Since what_changed is an array, you should cast to JArray to be able to access its elements and remove attribute_change token
var jObject = JObject.Parse(jsonText);
if (jObject["audit_entry"]?["what_changed"] is JArray array)
if (array[1] is JObject attribute)
attribute.Remove("attribute_change");
Console.WriteLine(jObject);
Search for the beginning attribute name and its end. Then concatenate the json string before/after into a new string. Perhaps a hack, but it will keep you coding until you find a more elegant solution.

How to convert Json array Keys to lower case?

I am getting a Json Array here is the JSON array
[
{
"customFieldName": "resolution",
"fieldName": "Resolution"
},
{
"customFieldName": "lastViewed",
"fieldName": "Last Viewed"
},
]
I want to convert the Keys to lower case please suggest the solution.
I tried to convert the JSON array to dictionary but not succeeded.
You can try reading all properties inside JsonArray and change the propertyname to lowercase
private static void ConvertToLowerCase(JArray jArray)
{
foreach (var item in jArray.Children())
{
foreach (var property in item.Children<JProperty>().ToList())
{
property.Replace(new JProperty(property.Name.ToLower(), property.Value));
}
}
}
call this method by passing the JArray
var jArray = JArray.Parse(jsonString);
ConvertToLowerCase(jArray);
Console.WriteLine(JsonConvert.SerializeObject(jArray));
Output
[{"customfieldname":"resolution","fieldname":"Resolution"},{"customfieldname":"lastViewed","fieldname":"Last Viewed"}]

Sorting JObject inside array by a field value

I have a JSON string like below:
{
"MetaData": {
"ResourcesUsed": 1
},
"Result": [
{
"locations": [
{
"country": "Papua New Guinea",
"city": "Jacquinot Bay",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-08T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
},{
"country": "Papua New Guinea2",
"city": "Jacquinot Bay2",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-02T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
}
]
}
]
}
I converted it to a JSON object using Newtonsoft. What I want to do is to sort the locations array(s) inside the Result array by the utcDate field nested in each locations item. I found the following thread: C# Sort JSON string keys. However, I could not still implement it since I have arrays inside my object, while that question deals purely with sorting objects inside objects alphabetically by property name.
Here is a piece of code that I wrote so far:
public string GenerateJson()
{
var model = (JObject)JsonConvert.DeserializeObject(data);
Sort(model);
}
private void Sort(JObject jObj)
{
var props = jObj["Result"][0]["locations"].ToList();
foreach (var prop in props)
{
prop.Remove();
}
foreach (var prop in props.OrderBy(p => p.Name))
{
jObj.Add(prop);
if (prop.Value is JObject)
Sort((JObject)prop.Value);
if (prop.Value is JArray)
{
Int32 iCount = prop.Value.Count();
for (Int32 iIterator = 0; iIterator < iCount; iIterator++)
if (prop.Value[iIterator] is JObject)
Sort((JObject)prop.Value[iIterator]);
}
}
}
You can sort each individual "Result[*].locations" array using LINQ as follows:
// Load the JSON without parsing or converting any dates.
var model = JsonConvert.DeserializeObject<JObject>(data, new JsonSerializerSettings{ DateParseHandling = DateParseHandling.None });
// Construct a serializer that converts all DateTime values to UTC
var serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings{ DateTimeZoneHandling = DateTimeZoneHandling.Utc });
foreach (var locations in model.SelectTokens("Result[*].locations").OfType<JArray>())
{
// Then sort the locations by utcDate converting the value to UTC at this time.
var query = from location in locations
let utcDate = location.SelectToken("locTypeAttributes.utcDate").ToObject<DateTime>(serializer)
orderby utcDate
select location;
locations.ReplaceAll(query.ToList());
}
Notes:
The JSON is initially loaded using DateParseHandling.None to prevent the "localDate" and "utcDate" strings from being prematurely interpreted as DateTime objects with a uniform DateTime.Kind.
(For a discussion of how Json.NET interprets strings that look like dates, see Serializing Dates in JSON.)
We then iterate through all "locations" arrays using SelectTokens("Result[*].locations") where [*] is the JSONPath wildcard character, selecting all entries in the "Results" array.
We then order each "locations" array by deserializing the nested locTypeAttributes.utcDate to a UTC date, then ordering using LINQ.
Finally the array is updated using JArray.ReplaceAll().
If any locTypeAttributes.utcDate property is missing, an exception will be thrown. You could instead deserialize to DateTime? if that is a possibility.
Working sample .Net fiddle here.

How get the array size using dynamic type

I am getting an array when I deserialize my JSON.
I can access the array with foreach.
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
foreach (dynamic result in obj.Results.output1.value.Values)
{
}
But I need to get size of the array to access the last element direct.
Eg.
obj.Results.output1.value.Values[size-1]
How can I do that?
Edit 1
I need to get for example the "Y" in "Values"
{
"Results": {
"output1": {
"type": "table",
"value": {
"ColumnNames": [
"I01",
"I02",
"I03",
"O01",
"Scored Probabilities for Class \"0\"",
"Scored Probabilities for Class \"1\"",
"Scored Probabilities for Class \"2\"",
"Scored Labels"
],
"Values": [
[
"-0.96624",
"0.02918",
"-0.44237",
null,
"3.25456957391002E-12",
"0.000107838139228988",
"2.76633869589205E-07",
"Y"
]
]
}
}
}
}
Edit 2
If I print I get this JSON
Console.WriteLine(obj.Results.output1.value.Values);
[
[
"-0.96624",
"0.02918",
"-0.44237",
null,
"3.25456957391002E-12",
"0.000107838139228988",
"2.76633869589205E-07",
"Y"
]
]
And the Count prints 1
Console.WriteLine(obj.Results.output1.value.Values.Count);
I almost there, I need the last element o the size to access by index in the inside array.
Edit 3
I could get the last element with:
Console.WriteLine(obj.Results.output1.value.Values[0].Last);
And the array size with:
Console.WriteLine(obj.Results.output1.value.Values[0].Count);
The JSON shows that Results is an object, not an array or list. What you're iterating is the properties. It's not a collection. It will be a JObject, which exposes .Last.
See here for more information
You simply need to write:
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
var lastProperty = obj.Last;
Might be useful to cast to a JObject (or a Dictionary<string, object> as well to help with future issues.
JObject obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
Accessing Values:
dynamic thing = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
var t = thing.Results.output1.value.Values.Count;
Here is the sample, I can get the result of 100.
ICollection collection = new int[100];
dynamic obj = collection;
Console.WriteLine(obj.Length);
int[] foo = new int[10];
int n = foo.Length;
you can get array size using ( arrayname.lenth ).try it.

How to show in list Facebook returned Json data?

i have json in object.
{
"data": [
{
"name": "Diljeet Jamwal",
"uid": 553042280,
"pic_square": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/274654_553042280_2105727599_q.jpg"
}, {
"name": "Jatinder Sharma",
"uid": 553042280,
"pic_square": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/274654_553042280_2105727599_q.jpg"
}]}
i want to show this in list in C#, how to do.
foreach (string data in yourlist)
{
console.WriteLine(data);
}
Of course do the parsing job to fill your list before ;)
You can try Newtonsoft.Json library http://nuget.org/packages/newtonsoft.json/
Example:
String yourdata = "..." // your JSON response
JObject json = JObject.Parse(yourdata);
after this, you can access your data:
String name = json["data"][0]["name"] //it should be Diljeet Jamwal
thanks to all, i have done this
dynamic array = JsonConvert.DeserializeObject(result.ToString());
foreach (var item in array)
{
foreach (var name in item["data"])
{
Response.Write(name["name"]);
}
}
using this

Categories

Resources