Parse Array inside of an JSON Object with C# - c#

I'm trying to parse an array inside of a json Object but it's not working, here is the code:
public void JsonParserPersonal(string file)
{
string fullname;
string email;
var json = System.IO.File.ReadAllText(file);
var objects = JObject.Parse(json);
var arrays = JArray.FromObject(json);
fullname = (string)objects["NameComponents"]["FullName"];
email = (string)arrays["EmailAddresses"]["ItemValue"];
SearchReplacePersonal(fullname, email);
}
Here is the JSON data:
{
"NameComponents": {
"FullName": "XXX"
},
"EmailAddresses": [
{
"IsPersonal": true,
"IsBusiness": false,
"FieldName": "Email1Address",
"DisplayTitle": "Email",
"ItemValue": "xxx#yyy.com"
}
]
}
All I want is to get the "ItemValue" inside of "EmailAddresses".
When I run this code, this is the error I get:
System.ArgumentException: 'Object serialized to String. JArray instance expected.'
I'm using Visual Studio 2019.
Thanks!

When accessing JArray, you should specify the index
var objects = JObject.Parse(json);
var jarray = objects["EmailAddresses"];
Console.WriteLine((string)objects["NameComponents"]["FullName"]);
Console.WriteLine((string)jarray[0]["ItemValue"]);
Or iterate JArray
foreach(var item in jarray)
{
foreach(JProperty property in item.Children())
{
Console.WriteLine($"{property.Name} - {property.Value}");
}
}

Related

C# Deserialize string of multiple arrays with json-string in it explicit to List<string>

i have a json-string, or bit more something like a "string of arrays":
"[
{
"type":"radio-group",
"label":"Radio-Button-Gruppe",
"name":"radio-group-1556028993486",
"className":"iCheck",
"values":[
{
"label":"aaaaaaa",
"value":"aaaaaaa"
},
{
"label":"bbbbbbbbb",
"value":"bbbbbbbbb"
},
{
"label":"cccccccccccc",
"value":"cccccccccccc"
}
]
}
],
[
...
],
[
{
"type":"header",
"label":"Überschrift"
}
]"
Now I want to have a List<string> of each array in this string. Something like:
List<string> x[0] = "{
"type":"radio-group",
"label":"Radio-Button-Gruppe",
"name":"radio-group-1556028993486",
"className":"iCheck",
"values":[
{
"label":"aaaaaaa",
"value":"aaaaaaa"
},
{
"label":"bbbbbbbbb",
"value":"bbbbbbbbb"
},
{
"label":"cccccccccccc",
"value":"cccccccccccc"
}
]
}"
What's the best way to do that?
I already tried out JsonConvert.DeserializeObject<IEnumerable<string>>() but my problem is that he wants to deserialize my jsons to an object. But I want to keep them as a string und put them to my list.
Why I need a list of string for each array?
Because I use the json-strings inside the arrays to render a form. each array show you a page of the form, and the json is the data for rendering this form.
to render this form i have to go through a loop through all of this arrays and render the json in it for every page.
You can use JsonConvert.DeserializeObject<IEnumerable<JToken>>(json) where json is each of your top level arrays. Then you can iterate through the results and use .ToString() on each JToken object.
As others have pointed out, you don't have valid JSON, so I didn't try to give a solution to parse out the top level arrays.
var json = #"[
{
""type"":""radio-group"",
""label"":""Radio-Button-Gruppe"",
""name"":""radio-group-1556028993486"",
""className"":""iCheck"",
""values"":[
{
""label"":""aaaaaaa"",
""value"":""aaaaaaa""
},
{
""label"":""bbbbbbbbb"",
""value"":""bbbbbbbbb""
},
{
""label"":""cccccccccccc"",
""value"":""cccccccccccc""
}
]
}
]";
var arrays = new[] { json };
var objectsAsStrings = new List<string>();
foreach (var array in arrays)
{
var tokens = JsonConvert.DeserializeObject<IEnumerable<JToken>>(array);
foreach (var token in tokens)
{
objectsAsStrings.Add(token.ToString());
}
}
var json = "yourjson";
var jsonnew = "[" + json+ "]";
var list = JsonConvert.DeserializeObject<dynamic>(jsonnew);
var result = new List<string>();
foreach (var item in list)
{
var str = JsonConvert.SerializeObject(item);
result.Add(str);
}
You can use this , too.

How to Modify JSON object inside JSON array in c#?

This is my Json Array
[
{
"gregdate": "06-03-2019",
"maldate": "22-07-1194",
"gregmonth": "March",
"selected_status": "1"
},
{
"gregdate": "04-05-2019",
"maldate": "21-09-1194",
"gregmonth": "May",
"selected_status": "1"
},
{
"gregdate": "03-06-2019",
"maldate": "20-10-1194",
"gregmonth": "June",
"selected_status": "1"
}
]
In this JSON Array, I want to change 2nd JSON Object "selected_status" value "1" to "0" without changing the position of the JSON Object.
You need to first convert you object array to JArray and then change its second object property from 1 to 0 like
string json = "You json here"; //Load your json
JArray jArray = JArray.Parse(json); //Parse it to JArray
var jObjects = jArray.ToObject<List<JObject>>(); //Get list of objects inside array
foreach (var obj in jObjects) //Loop through on a list
{
if (jObjects.IndexOf(obj) == 1) //Get 2nd object from array
{
foreach (var prop in obj.Properties()) //List 2nd objects properties
{
if (prop.Name == "selected_status") //Get desired property
obj["selected_status"] = 0; //Change its value
}
}
}
JArray outputArray = JArray.FromObject(jObjects); //Output array
Alternative:
As suggested by Brian Rogers you can directly query your JArray to replace its specific property value like,
string json = "You json here"; //Load your json
JArray jArray = JArray.Parse(json); //Parse it to JArray
jArray[1]["selected_status"] = "0"; //Querying your array to get property of 2nd object
string outputJson = jArray.ToString(); //Output json
Output: (from debugger)
This question helped me figure a couple things out - so here is what I came up with. I'm guessing that the json is a sample and what is desired is changing the status for a specific date, rather than just the second element. At least that's what I've been looking for. This is more dynamic and you don't have to worry about the position of the element.
string newJson = "";
if (SwitchStatus(jsonString, "04-05-2019", "0", out newJson))
{
Console.Write(newJson);
}
else
{
Console.WriteLine("Date Not Found");
}
Console.ReadLine();
static bool SwitchStatus(string jsonString, string searchBy, string switchTo, out string output)
{
dynamic jsonObj = JsonConvert.DeserializeObject(jsonString);
JToken status = jsonObj.SelectToken($"$..[?(#.gregdate == '{searchBy}')].selected_status");
if (status != null)
{
status.Replace(switchTo);
output = JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);
}
else
{
output = jsonString;
}
return status != null;
}

return array of arrays instead of array of objects with json.net

I need to return an array of arrays instead of an array of objects for a flot chart.
I can get the following:
data = [{"2012-10": 4140},{"2012-11": 10815},{"2012-12": 10444}];
but need (UPDATE fixed following line):
data = [["2012-10", 4140],["2012-11", 10815],["2012-12", 10444]];
Here is the c# which is parsing inbound json from another source:
public async Task<ActionResult> Chart(string custid)
{
//Get the financial results from DRT
var response = await DominoJSON.getJSON(custid, "drtHistory", "DRT");
JArray UOVol = new JArray();
var array = JArray.Parse(response);
foreach (var token in array)
{
JObject o = JObject.Parse(token.ToString());
int uovol = Convert.ToInt32(o["UOVol"]);
string uodate = o.SelectToken("DATE").ToString();
JObject UOItem = new JObject(new JProperty(uodate, uovol));
UOVol.Add(UOItem);
}
string resultUO = UOVol.ToString();
ViewBag.UOData = resultUO;
return View();
}
And the inbound json being parsed:
[
{
"DATE":"2012-10",
"UOVol":4140,
"FIRev":180,
"AFRev":692.75,
"ABRev":2900,
"OWRev":3791.25,
},
{
"DATE":"2012-11",
"UOVol":10815,
"FIRev":60,
"AFRev":170,
"ABRev":0,
"OWRev":3037.5,
},
{
"DATE":"2012-12",
"UOVol":10444,
"FIRev":40,
"AFRev":514.25,
"ABRev":1450,
"OWRev":7500,
}
]
I can't figure out how to turn the JObjects to arrays. I have tried this with other approaches including using a dictionary and list. Any help or alternate solutions would be helpful. Using VS2013, mvc 5 and EF 6.
Try this:
class Program
{
static void Main(string[] args)
{
string jsonIn = #"
[
{
""DATE"": ""2012-10"",
""UOVol"": 4140,
""FIRev"": 180,
""AFRev"": 692.75,
""ABRev"": 2900,
""OWRev"": 3791.25
},
{
""DATE"": ""2012-11"",
""UOVol"": 10815,
""FIRev"": 60,
""AFRev"": 170,
""ABRev"": 0,
""OWRev"": 3037.5
},
{
""DATE"": ""2012-12"",
""UOVol"": 10444,
""FIRev"": 40,
""AFRev"": 514.25,
""ABRev"": 1450,
""OWRev"": 7500
}
]";
JArray arrayIn = JArray.Parse(jsonIn);
JArray arrayOut = new JArray();
foreach (JObject jo in arrayIn.Children<JObject>())
{
JArray ja = new JArray();
ja.Add(jo["DATE"]);
ja.Add(jo["UOVol"]);
arrayOut.Add(ja);
}
string jsonOut = arrayOut.ToString(Formatting.None);
Console.WriteLine(jsonOut);
}
}
Output:
[["2012-10",4140],["2012-11",10815],["2012-12",10444]]

Parsing a JSON array using Json.Net

I'm working with Json.Net to parse an array. What I'm trying to do is to pull the name/value pairs out of the array and assign them to specific variables while parsing the JObject.
Here's what I've got in the array:
[
{
"General": "At this time we do not have any frequent support requests."
},
{
"Support": "For support inquires, please see our support page."
}
]
And here's what I've got in the C#:
WebRequest objRequest = HttpWebRequest.Create(dest);
WebResponse objResponse = objRequest.GetResponse();
using (StreamReader reader = new StreamReader(objResponse.GetResponseStream()))
{
string json = reader.ReadToEnd();
JArray a = JArray.Parse(json);
//Here's where I'm stumped
}
I'm fairly new to JSON and Json.Net, so it might be a basic solution for someone else. I basically just need to assign the name/value pairs in a foreach loop so that I can output the data on the front-end. Has anyone done this before?
You can get at the data values like this:
string json = #"
[
{ ""General"" : ""At this time we do not have any frequent support requests."" },
{ ""Support"" : ""For support inquires, please see our support page."" }
]";
JArray a = JArray.Parse(json);
foreach (JObject o in a.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
string name = p.Name;
string value = (string)p.Value;
Console.WriteLine(name + " -- " + value);
}
}
Fiddle: https://dotnetfiddle.net/uox4Vt
Use Manatee.Json
https://github.com/gregsdennis/Manatee.Json/wiki/Usage
And you can convert the entire object to a string, filename.json is expected to be located in documents folder.
var text = File.ReadAllText("filename.json");
var json = JsonValue.Parse(text);
while (JsonValue.Null != null)
{
Console.WriteLine(json.ToString());
}
Console.ReadLine();
I know this is about Json.NET but times are a-changing so if anybody stumbles here while using .NET Core/5+ System.Text.Json please don't despair because
Try the new System.Text.Json APIs from .NET Blog show an example of this.
[
{
"date": "2013-01-07T00:00:00Z",
"temp": 23,
},
{
"date": "2013-01-08T00:00:00Z",
"temp": 28,
},
{
"date": "2013-01-14T00:00:00Z",
"temp": 8,
},
]
...
using (JsonDocument document = JsonDocument.Parse(json, options))
{
int sumOfAllTemperatures = 0;
int count = 0;
foreach (JsonElement element in document.RootElement.EnumerateArray())
{
DateTimeOffset date = element.GetProperty("date").GetDateTimeOffset();
(...)

Convert Newtonsoft.Json.Linq.JArray to a list of specific object type

I have the following variable of type {Newtonsoft.Json.Linq.JArray}.
properties["Value"] {[
{
"Name": "Username",
"Selected": true
},
{
"Name": "Password",
"Selected": true
}
]}
What I want to accomplish is to convert this to List<SelectableEnumItem> where SelectableEnumItem is the following type:
public class SelectableEnumItem
{
public string Name { get; set; }
public bool Selected { get; set; }
}
I am rather new to programming and I am not sure whether this is possible. Any help with working example will be greatly appreciated.
Just call array.ToObject<List<SelectableEnumItem>>() method. It will return what you need.
Documentation: Convert JSON to a Type
The example in the question is a simpler case where the property names matched exactly in json and in code. If the property names do not exactly match, e.g. property in json is "first_name": "Mark" and the property in code is FirstName then use the Select method as follows
List<SelectableEnumItem> items = ((JArray)array).Select(x => new SelectableEnumItem
{
FirstName = (string)x["first_name"],
Selected = (bool)x["selected"]
}).ToList();
The API return value in my case as shown here:
{
"pageIndex": 1,
"pageSize": 10,
"totalCount": 1,
"totalPageCount": 1,
"items": [
{
"firstName": "Stephen",
"otherNames": "Ebichondo",
"phoneNumber": "+254721250736",
"gender": 0,
"clientStatus": 0,
"dateOfBirth": "1979-08-16T00:00:00",
"nationalID": "21734397",
"emailAddress": "sebichondo#gmail.com",
"id": 1,
"addedDate": "2018-02-02T00:00:00",
"modifiedDate": "2018-02-02T00:00:00"
}
],
"hasPreviousPage": false,
"hasNextPage": false
}
The conversion of the items array to list of clients was handled as shown here:
if (responseMessage.IsSuccessStatusCode)
{
var responseData = responseMessage.Content.ReadAsStringAsync().Result;
JObject result = JObject.Parse(responseData);
var clientarray = result["items"].Value<JArray>();
List<Client> clients = clientarray.ToObject<List<Client>>();
return View(clients);
}
I can think of different method to achieve the same
IList<SelectableEnumItem> result= array;
or (i had some situation that this one didn't work well)
var result = (List<SelectableEnumItem>) array;
or use linq extension
var result = array.CastTo<List<SelectableEnumItem>>();
or
var result= array.Select(x=> x).ToArray<SelectableEnumItem>();
or more explictly
var result= array.Select(x=> new SelectableEnumItem{FirstName= x.Name, Selected = bool.Parse(x.selected) });
please pay attention in above solution I used dynamic Object
I can think of some more solutions that are combinations of above solutions. but I think it covers almost all available methods out there.
Myself I use the first one
using Newtonsoft.Json.Linq;
using System.Linq;
using System.IO;
using System.Collections.Generic;
public List<string> GetJsonValues(string filePath, string propertyName)
{
List<string> values = new List<string>();
string read = string.Empty;
using (StreamReader r = new StreamReader(filePath))
{
var json = r.ReadToEnd();
var jObj = JObject.Parse(json);
foreach (var j in jObj.Properties())
{
if (j.Name.Equals(propertyName))
{
var value = jObj[j.Name] as JArray;
return values = value.ToObject<List<string>>();
}
}
return values;
}
}
Use IList to get the JArray Count and Use Loop to Convert into List
var array = result["items"].Value<JArray>();
IList collection = (IList)array;
var list = new List<string>();
for (int i = 0; i < collection.Count; j++)
{
list.Add(collection[i].ToString());
}

Categories

Resources