Reputation: 113
I have a JSON string like below
{"data":[{"report_header":{"c1":{"name":"COLUMN1","type":"java.lang.String"},"c2":{"name":"COLUMN2","type":"java.lang.String"}},"report_row":[{"c1":"2019","c2":"TEST123"},{"c1":"2019","c2":"TEST345"},{"c1":"2020","c2":"TEST567"}]}],"message":["OK"],"status":200}
I have used json2csharp and created classes.
public class C1
{
public string name { get; set; }
public string type { get; set; }
}
public class C2
{
public string name { get; set; }
public string type { get; set; }
}
public class ReportHeader
{
public C1 c1 { get; set; }
public C2 c2 { get; set; }
}
public class ReportRow
{
public string c1 { get; set; }
public string c2 { get; set; }
}
public class Datum
{
public ReportHeader report_header { get; set; }
public List<ReportRow> report_row { get; set; }
}
public class RootObject
{
public List<Datum> data { get; set; }
public List<string> message { get; set; }
public int status { get; set; }
}
And reading values using below code
var jss = new JavaScriptSerializer();
var ListExample = jss.Deserialize<RootObject>(result);
IList<Datum> listData = ListExample.data;
IList<ReportRow> reportRows = listData[0].report_row;
foreach (ReportRow row in reportRows)
{
Console.WriteLine(row.c1.ToString());
Console.WriteLine(row.c2.ToString());
}
My question is how I can modify above code to make it more generic so that in can handle more columns. Like what if I have more columns like c3,c4 in Jason. How can I iterate through them without re-writing Report Row class for all such use cases.
Upvotes: 2
Views: 5567
Reputation: 23298
You can easily access all properties inside report_row
item using Newtonsoft.Json.Linq
, by iterating through data
array items, and then iterating through every report_row
var obj = JObject.Parse(json);
foreach (var dataItem in obj["data"])
{
foreach (var row in dataItem["report_row"])
{
var c1 = row["c1"].Value<int>();
var c2 = row["c2"].Value<string>();
//var c3 = ...
}
}
Another option is to deserialize a json into IDictionary<string,object>
using Deserialize
method of JavaScriptSerializer
, and then access dictionary keys and values
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<IDictionary<string,object>>(json);
But using JavaScriptSerializer
class is not recommended
Upvotes: 2
Reputation: 23541
You can use a Dictionary
to achieve the expected result without trouble:
var root = JsonConvert.DeserializeObject<RootObject>(result);
var report_row = root.data[0].report_row;
foreach (var reportRow in report_row)
foreach (var row in reportRow)
Console.WriteLine(row.Key + ", " + row.Value);
output example:
c1, 2019
c2, TEST123
c3, HERE IS C3
c1, 2019
c2, TEST345
c1, 2020
c2, TEST567
With the following model
public class C1
{
public string name { get; set; }
public string type { get; set; }
}
public class C2
{
public string name { get; set; }
public string type { get; set; }
}
public class ReportHeader
{
public C1 c1 { get; set; }
public C2 c2 { get; set; }
}
public class Datum
{
public ReportHeader report_header { get; set; }
public List<Dictionary<string, string>> report_row { get; set; }
}
public class RootObject
{
public List<Datum> data { get; set; }
public List<string> message { get; set; }
public int status { get; set; }
}
Edit: Since OP updated the json, here is a outdated demo to try out. The idea of using a Dictionary
is exactly the same though.
Upvotes: 1