Parse JSON array in c# to read array collection inside json - c#

I have a below Jason format in which the Claims will be a array collection now I need to read all the Claims(which is a collection in below json) related to the policyid from c# , could anyone help me resoling it
{
"ClaimList": [{
"Claims": ["CL8901"],
"PolicyID": "W1234sd",
"ClaimsCount": 1
}, {
"Claims": ["CL3456", "CL1234"],
"PolicyID": "T1234sd",
"ClaimsCount": 2
}, {
"Claims": ["CL1321"],
"PolicyID": "C1234sd",
"ClaimsCount": 1
}]
}

string json = Util.ReadLine<string>();
JObject.Parse(json).SelectToken("ClaimList").Select(cl => new
{
PolicyId = cl.SelectToken("PolicyID"),
Claims = cl.SelectToken("Claims").ToObject<List<string>>()
}).Dump();
Linqpad code
http://share.linqpad.net/vqoav5.linq

To achieve what you need, do the following:
Follow my answer here to create C# classes for your json
Use NewtonSoft NuGet library to deserialize the JSON to C# objects
Perform whatever processing you need on the deserialized items
Here is some code once you have done the above:
var claims = JsonConvert.DeserializeObject<Rootobject>("YourJsonHere");
IEnumerable<Claimlist> claimsForPolicy=
claims.ClaimList.Where(x => x.PolicyID == "whateverYouNeed");

If you can use the Json.NET library (NuGet), this is pretty straightforward. First make sure you have a Claim class that has the structure of those inner objects in your JSON:
class Claim
{
public List<string> Claims { get; set; }
public string PolicyID { get; set; }
public int ClaimsCount { get; set; }
}
Having that class available, you can use Json.NET to do something like this:
using Newtonsoft.Json;
// ...
string yourJson = getYourJsonStringSomehow();
var claimsDict =
JsonConvert.DeserializeObject<Dictionary<string, List<Claim>>>(yourJson);
That will produce a Dictionary with one key: "ClaimsList", and the value will be a List of your Claim objects:
var claimsList = claimsDict["ClaimsList"];
var firstClaim = claimsList[0];
Console.WriteLine(firstClaim.PolicyID);
// Should print W1234sd

You can try this, first lets create a Json class for your json data:
public class JsonDoc
{
//I am adding an index on constructor for looping purposes
public JsonDoc(string json, int index)
{
JObject jObject = JObject.Parse(json);
JToken jResult = jObject["ClaimList"];
Claims = jResult[index]["Claims"].ToObject<string[]>();
}
//This constructor will return the number of count under ClaimList node
public JsonDoc(string json)
{
JObject jObject = JObject.Parse(json);
JToken jResult = jObject["ClaimList"][0];
intCount = jResult.Count();
}
private string[] Claims { get; set; }
public int intCount { get; set; }
}
Then to use this class for your Json data, first add a reference of Newtonsoft Json.
using Newtonsoft.Json.Linq;
Then on your sample data, I read all the data via file using StreamReader, loop on it and put all the data under a List:
private static void Main(string[] args)
{
using (StreamReader sr = new StreamReader(#"C:\Folder\myjson.json"))
{
string json = sr.ReadToEnd();
JsonDoc jSon = new JsonDoc(json);
//This will get the length of the array under ClaimList node
int intCount = jSon.intCount;
List<JsonDoc> lstResult = new List<JsonDoc>();
for (int x = 0; x < intCount; x++)
{
lstResult.Add(new JsonDoc(json, x));
}
}
}
The result is a List of JsonDoc class with array of string as part of property. This array of string is the result on your Claims Node. This JsonDoc class contains property Claims which is a string array which contains your Claims node:

Related

How do I parse a JProperty to retreive nested values with variable keys

Given I have a JObject:
{
"results": {
"payroll_report": {
"314568": {
"user_id": 314568,
"client_id": "484781",
"start_date": "2020-03-29",
"end_date": "2020-04-04",
"total_re_seconds": 49260,
"total_pto_seconds": 94716,
"total_work_seconds": 143976,
"total_paid_break_seconds": 0,
"total_unpaid_break_seconds": 0,
"pto_seconds": {
"22322828": 57348,
"12597955": 37368
},
"total_ot_seconds": 0,
"total_dt_seconds": 0,
"timesheet_count": 16
}
}
},
}
How do I parse it so I can know the number of pto_seconds for 22322828?
I am already able to get total_pro_seconds and other elements at that level, but I can't figure out how to get the nested values.
My assumption is you want to access all the nested Key-Value pairs under the pto_seconds element and assume that json structure is always as it was given on the example.
Here is the full code to iterate over the list and get values. My second assumption is values are long type, that is why I used jToken.First().Value<long>(). If it is decimal or other types you can change it accordingly.
var jObject = JsonConvert.DeserializeObject<JObject>(json);
var jTokenList = jObject["results"]["payroll_report"]["314568"]["pto_seconds"].Children().ToList();
foreach (var jToken in jTokenList)
{
var ptoSecondKey = (jToken as JProperty).Name;
var ptoSecondValue = jToken.First().Value<long>();
}
Alternative method(without using JObject):
You can have real object representation of your JSON structure and you can use DeserializeObject<T> method to parse and return results as your object.
Here below you can find classes for your JSON:
public class ResultsMain
{
[JsonProperty("results")]
public ResultsDetail Results { get; set; }
}
public class ResultsDetail
{
[JsonProperty("payroll_report")]
public PayrollReport PayrollReport { get; set; }
}
public class PayrollReport
{
[JsonProperty("314568")]
public PayrollReportDetail Detail { get; set; }
}
public class PayrollReportDetail
{
[JsonProperty("pto_seconds")]
public Dictionary<string, long> PtoSeconds { get; set; }
}
To deserialize the JSON to your .NET type, you need below one line of code:
var resultsMain = JsonConvert.DeserializeObject<ResultsMain>(json);
Here is a snapshot of resultMain object:
You can enumerate over JObject, (if your initial JObject is named jObject)
var toEnumerate = (JObject)(jObject["results"]["payroll_report"]["314568"]["pto_seconds"]);
foreach(var pair in toEnumerate)
{
Console.WriteLine("Key: " + pair.Key);
Console.WriteLine("Value: " + pair.Value);
}
output:
Key: 22322828
Value: 57348
Key: 12597955
Value: 37368
I don't see any issue. See below 2 options are
static void Main(string[] args)
{
string json = File.ReadAllText("json1.json");
JObject jObject = JObject.Parse(json);
var results = jObject["results"];
var payroll_report = results["payroll_report"];
var user314568 = payroll_report["314568"];
var total_pto_seconds = user314568["total_pto_seconds"];
var pto_seconds = user314568["pto_seconds"];
///**************option1***********************
var val1 = pto_seconds["22322828"];
var val2 = pto_seconds["12597955"];
Console.WriteLine($"22322828: {val1}");
Console.WriteLine($"22322828: {val2}");
///**************option2***********************
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(pto_seconds.ToString());
foreach (var item in dict)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
Console.ReadLine();
}

Deserializing Json array with variable names first using C# Json.NET

I'm getting an irregular JSON array from the Census Bureau's public api.
The variable names are all in the first element, and I'm having trouble deserializing it.
http://api.census.gov/data/2014/pep/agesex?get=AGE,POP,SEX&for=us:*&DATE=7
gives me JSON like this:
[["AGE","POP","SEX","DATE","us"],
["0","3948350","0","7","1"],
["1","3962123","0","7","1"],
["2","3957772","0","7","1"],
["3","4005190","0","7","1"],
["4","4003448","0","7","1"],
["5","4004858","0","7","1"],
["6","4134352","0","7","1"],
["7","4154000","0","7","1"]]
I can successfully deserialize this using:
var test1 = JsonConvert.DeserializeObject<String[][]>(jsonStr);
However, I'm trying to deserialize it to a class like this:
public class TestClass
{
public string AGE { get; set; }
public string POP { get; set; }
public string SEX { get; set; }
public string DATE { get; set; }
public string us { get; set; }
}
I'm trying to do this:
var test2 = JsonConvert.DeserializeObject<TestClass[]>(jsonStr);
But I'm getting the following exception:
An exception of type 'Newtonsoft.Json.JsonSerializationException'
occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Cannot create and populate list type
TestClass. Path '[0]', line 1, position
2.
There's two parts to this.
First is turning the JSON in to data usable in C#, and the second is turning that data in to nice objects.
Here's a working dotNetFiddle.net example of the following code: https://dotnetfiddle.net/Cr0aRL
Each row in your JSON is made up of an array of strings.
So that's an array of an array of strings.
In C# that can be written as string[][].
So to turn the JSON in to usable data with JSON.Net you can do:
var json = "[[\"AGE\",\"POP\",\"SEX\",\"DATE\",\"us\"],[\"0\",\"3948350\",\"0\",\"7\",\"1\"],[\"1\",\"3962123\",\"0\",\"7\",\"1\"],[\"2\",\"3957772\",\"0\",\"7\",\"1\"],[\"3\",\"4005190\",\"0\",\"7\",\"1\"],[\"4\",\"4003448\",\"0\",\"7\",\"1\"],[\"5\",\"4004858\",\"0\",\"7\",\"1\"],[\"6\",\"4134352\",\"0\",\"7\",\"1\"],[\"7\",\"4154000\",\"0\",\"7\",\"1\"]]";
var rawData = JsonConvert.DeserializeObject<string[][]>(json);
Next up is is turning that data in to objects.
The first row is the header, containing the column names, so we want to grab that, and then figure out the column index for each column name.
var headerRow = rawData.First();
var ageIndex = Array.IndexOf(headerRow, "AGE");
var popIndex = Array.IndexOf(headerRow, "POP");
var sexIndex = Array.IndexOf(headerRow, "SEX");
var dateIndex = Array.IndexOf(headerRow, "DATE");
var usIndex = Array.IndexOf(headerRow, "us");
Now we have the indexes, we need to take each row, and convert it in to the appropriate object. I've used LINQ for this as it's very good at representing data processing in a clear way.
var testData = rawData
.Skip(1) //The first row is a header, not data
.Select(dataRow => new TestClass()
{
AGE = dataRow[ageIndex],
POP = dataRow[popIndex],
SEX = dataRow[sexIndex],
DATE = dataRow[dateIndex],
us = dataRow[usIndex]
});
Finally a bit of testing, to make sure you have the data you're expecting.
//Get the second data row as an example
var example = testData.Skip(1).First();
//Output example POP to check value
Console.WriteLine(example.POP);
Everything above is very manual.
You have to know what headers you expect, then you manually find the indexes, then you manually map the rows to objects.
It's quite possible for a simple use case that doing that is fine. But in larger and/or more complex systems you might want/need to automate those steps.
Automating those steps is possible, but is beyond the scope of this answer as how you approach it can depend on a lot of different factors.
You could make a custom JsonConverter to handle this conversion during deserialization. The conversion code is really not much different than other answers here, except that it is encapsulated into a separate class so that you don't muddy up your main code with the conversion details. From the point of view of your main code it "just works".
Here is how to write the converter:
public class TestClassArrayConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(TestClass[]));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JArray table = JArray.Load(reader);
TestClass[] items = new TestClass[table.Count - 1];
for (int i = 1; i < table.Count; i++)
{
JArray row = (JArray)table[i];
items[i - 1] = new TestClass
{
AGE = (string)row[0],
POP = (string)row[1],
SEX = (string)row[2],
DATE = (string)row[3],
us = (string)row[4]
};
}
return items;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
And here is how you would use it:
var test2 = JsonConvert.DeserializeObject<TestClass[]>(jsonStr, new TestClassArrayConverter());
Fiddle: https://dotnetfiddle.net/68Q0KT
You have to do the processing on your own, as there is no way the json deserializer can know, how to put the values into the respecitve variables.
If you know, this will be exactly this structure, you could for instance add an appropriate constructor
public TestClass(string[] values) {
AGE = values[0];
...
}
to your class. Then serialize your result to array of arrays of string and then pass the inner arrays to your constructor.
var t1 = JsonConvert.DeserializeObject<string[][]>(jsonStr);
//skip the first entry, as this contains the headers
var t2 = t1.Skip(1).Select(x=> new TestClass(x));
If your structure varies, you'll have to write some more complicated mapping code.
You will have to do some custom mapping as your Json does not have any naming conventions so you will have to work with the data in array and index formats. This will work:
var jsonStr = "[[\"AGE\",\"POP\",\"SEX\",\"DATE\",\"us\"], [\"0\",\"3948350\",\"0\",\"7\",\"1\"], [\"1\",\"3962123\",\"0\",\"7\",\"1\"], [\"2\",\"3957772\",\"0\",\"7\",\"1\"], [\"3\",\"4005190\",\"0\",\"7\",\"1\"], [\"4\",\"4003448\",\"0\",\"7\",\"1\"], [\"5\",\"4004858\",\"0\",\"7\",\"1\"], [\"6\",\"4134352\",\"0\",\"7\",\"1\"], [\"7\",\"4154000\",\"0\",\"7\",\"1\"]]";
var test2 = JsonConvert.DeserializeObject<string[][]>(jsonStr);
var test3 = test2.Select(x => new TestClass()
{
AGE = x[0].ToString(),
POP = x[1].ToString(),
SEX = x[2].ToString(),
DATE = x[3].ToString(),
us = x[4].ToString()
}).ToList();
//test Case
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
namespace ApiController.Test
{
[TestClass]
public class DownloadIrregularJsonStringObjects
{
string ApiKey => "YourPersonalCensusKey";
/// <summary>
/// You have to get your own ApiKey from the Census Website
/// </summary>
[TestMethod]
public void TestGetItem()
{
string url = $"http://api.census.gov/data/timeseries/healthins/sahie?get=NIC_PT,NAME,NUI_PT&for=county:*&in=state:*&time=2015&key={YourPersonalCensusKey}";
string expected = "Autauga County, AL";
IList<HealthData> actual = ApiController.DownloadIrregularJsonStringObjects.GetCensusHealthData(url);
Assert.AreEqual(actual[0].NAME, expected);
}
}
}
///Actual Assembly
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
namespace ApiController
{
public class DownloadIrregularJsonStringObjects
{
public static IList<HealthData> GetCensusHealthData(string url)
{
var json = GetData(url);
var rawData = JsonConvert.DeserializeObject<string[][]>(json);
var headerRow = rawData.First();
var nic_pt_Index = Array.IndexOf(headerRow, "NIC_PT");
var name_Index = Array.IndexOf(headerRow, "NAME");
var nui_pt_Index = Array.IndexOf(headerRow, "NUI_PT");
IList<HealthData> retVal = new List<HealthData>();
foreach (var r in rawData.Skip(1))
{
HealthData dataRow = new HealthData();
dataRow.NIC_PT = r[nic_pt_Index];
dataRow.NAME = r[name_Index];
dataRow.NUI_PT = r[nui_pt_Index];
retVal.Add(dataRow);
}
return retVal;
}
private static string GetData(string url)
{
using (var w = new WebClient())
{
var jsonData = string.Empty;
jsonData = w.DownloadString(url);
return jsonData;
}
}
}
public class HealthData
{
public string NIC_PT { get; set; }
public string NAME { get; set; }
public string NUI_PT { get; set; }
}
}

Deserialize Json with no name Fields and Format string, array

I have the following json object:
[
"sd",
[
"sdg\u0026e",
"sdlc",
"sdccu",
"sdsu webportal",
"sdsu",
"sdsu blackboard",
"sdcc",
"sd card",
"sdn",
"sdro"
]
]
Obtained from google suggest with this URL:
http://suggestqueries.google.com/complete/search?output=firefox&hl=en&q=sd
I have tried deserializing it like this:
dynamic objson = JsonConvert.DeserializeObject(res);
But it is not useful because I need it into a class object.
And also using types:
public class SuggestClass
{
public string search { get; set; }
public string[] terms { get; set; }
}
var result = JsonConvert.DeserializeObject<SuggestClass>(res);
But it always throw exception.
I do not know how can I do it without having name fields.
EDIT:
Another JSON:
["text",["textura","textos bonitos","texto argumentativo","textos","textos de amor","texto expositivo","texturas minecraft","textos de reflexion","texture pack minecraft","textos en ingles"]]
That's tricky...
But since it's an array, you could create a factory method to parse SuggestClass out of given JArray.
public void SomeMethod()
{
string json =
"[\"sd\",[\"sdg\u0026e\",\"sdlc\",\"sdccu\"" +
",\"sdsu webportal\",\"sdsu\",\"sdsu blackboard\","+
"\"sdcc\",\"sd card\",\"sdn\",\"sdro\"]]";
var factory = new Factory();
var suggest = factory.Create(json);
Console.WriteLine(suggest);
}
public class Factory
{
public SuggestClass Create(string json)
{
var array = JArray.Parse(json);
string search = array[0].ToString();
string[] terms = array[1].ToArray().Select(item => item.ToString()).ToArray();
return new SuggestClass {Search = search, Terms = terms};
}
}
public class SuggestClass
{
public string Search { get; set; }
public IEnumerable<string> Terms { get; set; }
public override string ToString()
{
return string.Format("Search={0},Terms=[{1}]",
Search, string.Join(",", Terms));
}
}
Would print to console:
Search=sd,Terms=[sdg&e,sdlc,sdccu,sdsu webportal,sdsu,sdsu blackboard,sdcc,sd card,sdn,sdro]
And the other JSON you provided:
Search=sd,Terms=[sdg&e,sdlc,sdccu,sdsu webportal,sdsu,sdsu blackboard,sdcc,sd card,sdn,sdro]
Search=text,Terms=[textura,textos bonitos,texto argumentativo,textos,textos de amor,texto expositivo,texturas minecraft,textos de reflexion,texture pack minecraft,textos en ingles]
Just used the JSON visualizer in visual studio. This is how it looks like.
It is an array of multiple types. The following code can be used to parse it. But it is not perfect yet.
var objson = JsonConvert.DeserializeObject<object[]>(res);
So I think #Mikko answer has a better approach..

How do I incrementally serialize and deserialize JSON with ServiceStack?

What I have is this:
string json = #"{'number': 3, 'object' : { 't' : 3, 'whatever' : 'hi', 'str': 'test'}";
How do I read the fields until I'm at 'object', then serialize the whole 'object' into a .NET type and then continue parsing?
Define your types:
public class Object
{
public int t { get; set; }
public string whatever { get; set; }
public string str { get; set; }
}
public class RootObject
{
public int number { get; set; }
public Object object { get; set; }
}
Then just deserialize it:
string json = #"{'number': 3, 'object' : { 't' : 3, 'whatever' : 'hi', 'str': 'test'}";
var deserialized = JsonConvert.DeserializeObject<RootObject>(json);
//do what you want
UPDATE
You didn't say it's dynamic, for such parsing there is many solutions.
Check the following:
Using JSON.NET for dynamic JSON parsing
Using C# 4.0 and dynamic to parse JSON
Deserialize JSON into C# dynamic object?
Parse JSON block with dynamic variables
Turning JSON into a ExpandoObject
To handle a dynamic type: use dynamic, to handle dynamic data such as XML or JSON use ExpandoObject.
UPDATE 2
Using Anonymous types to deserialize JSON data
UPDATE 3
Will this work for you:
string json = "{\"number\": 3, \"object\" : { \"t\" : 3, \"whatever\" : \"hi\", \"str\": \"test\"}}";
var deserialized = SimpleJson.DeserializeObject<IDictionary<string, object>>(json);
var yourObject = deserialized["object"] as IDictionary<string, object>;
if (yourObject != null)
{
var tValue = yourObject.GetValue("t");
var whateverValue = yourObject.GetValue("whatever");
var strValue = yourObject.GetValue("str");
}
public static object GetValue(this IDictionary<string,object> yourObject, string propertyName)
{
return yourObject.FirstOrDefault(p => p.Key == propertyName).Value;
}
Final result:
Or change to the following
if (yourObject != null)
{
foreach (string key in yourObject.Keys)
{
var myValue = yourObject.GetValue(key);
}
}
UPDATE 4 - SERVICE STACK
string json = "{\"number\": 3, \"object\" : { \"t\" : 3, \"whatever\" : \"hi\", \"str\": \"test\"}}";
var deserialized = JsonObject.Parse(json);
var yourObject = deserialized.Get<IDictionary<string, object>>("object");
if (yourObject != null)
{
foreach (string key in yourObject.Keys)
{
var myValue = yourObject.GetValue(key);
}
}
Result:
Look at ServiceStack's Dynamic JSON Parsing:
var myPoco = JsonObject.Parse(json)
.GetUnescpaed("object")
.FromJson<TMyPoco>();
This works for deserializing, I will update once I got serializing.
foreach(KeyValuePair<String,String> entry in JsonObject.Parse(json))
{
}
Edit: Looks like this only works for json objects. I still don't know how to iterate over JsonArrayObjects

How to get values from a Jobject

I am using the Newtonsoft JSon c# plugin. I jave a JArray
{"data":[{"name":"Wesley 1","id":"616611941"},{"name":"Wesley 2","id":"100000138033375"},..............
I was wondering is there a way to loop though each object between the curly braces and extract the name and id of each entry?
Thanks to anyone who can help
According to some other questions you could try:
var array = JArray.Parse(json);
and then do a
foreach(var item in array)
// do something
dynamic dynObj = JsonConvert.DeserializeObject(json);
foreach (var item in dynObj.data)
{
Console.WriteLine("{0} {1}",item.name,item.id);
}
using jQuery you can do this. First loop will go thorough each item in array. second loop will get the key, value in each array item
$.each(data, function() {
$.each(this, function(key, value) {
//do what ever you want
});
});
EDIT
OK. You got some good answers from others. Here is another way.
namespace
using System.Web.Script.Serialization;
You add strongly typed class that maps data in the json
public class wordList
{
public List<NameId> data { get; set; }
public wordList()
{
data = new List<NameId>();
}
}
public class NameId
{
public string name { get; set; }
public string id { get; set; }
}
then you call
string jsonObj = #"{""data"":[{""name"":""Wesley 1"",""id"":""616611941""},{""name"":""Wesley 2"",""id"":""100000138033375""}]}";
JavaScriptSerializer jsSer = new JavaScriptSerializer();
wordList wl = jsSer.Deserialize<wordList>(jsonObj);
You can loop through the WordList to get the name, id values
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
List<JObject> data = JsonConvert.DeserializeObject<List<JObject>>(requestBody);
foreach(JObject d in data)
{
string name = d.GetValue("name").ToString();
string id = d.GetValue("id").ToString();
}

Categories