I'm trying to parse a JSON response that includes something I'm not quite familiar with, nor have I seen in the wild that often.
Inside one of the JSON objects, there is a dynamically named JSON object.
In this example, there is a JSON object inside "bugs"
named "12345"
which correlates to a bug number.
{
"bugs" : {
"12345" : {
"comments" : [
{
"id" : 1,
"text" : "Description 1"
},
{
"id" : 2,
"text" : "Description 2"
}
]
}
}
}
What I'm curious about is: What would be the most effective way to parse a dynamically-named JSON object like this?
Given some JSON Utility tools like
They will take a JSON response like the one above and morph it into classes like the following respectfully:
jsonutils
public class Comment
{
public int id { get; set; }
public string text { get; set; }
}
public class 12345
{
public IList<Comment> comments { get; set; }
}
public class Bugs
{
public 12345 12345 { get; set; }
}
public class Root
{
public Bugs bugs { get; set; }
}
json2charp
public class Comment
{
public int id { get; set; }
public string text { get; set; }
}
public class __invalid_type__12345
{
public List<Comment> comments { get; set; }
}
public class Bugs
{
public __invalid_type__12345 __invalid_name__12345 { get; set; }
}
public class RootObject
{
public Bugs bugs { get; set; }
}
The problem about this is that it generates a class
with a dynamic name. Thus subsequent queries with other identifiers to this API would result in a failure because the name does not match up nor would a generated [JsonProperty("")]
as it would contain the dynamic class name as per the generated examples above.
Although the JSON is valid, this seems to be a limitation with JSON that is formatted this way. Unfortunately I do not have any control on this JSON API, so I'm curious what the best way to approach this problem would be?
The JSON. parse() method parses a JSON string, constructing the JavaScript value or object described by the string. An optional reviver function can be provided to perform a transformation on the resulting object before it is returned.
A dynamic JSON file will be created to store the array of JSON objects. Consider, we have a database named gfg, a table named userdata. Now, here is the PHP code to fetch data from database and store them into JSON file named gfgfuserdetails. json by converting them into an array of JSON objects.
Parsing JSON is much more efficient than parsing object literals in JavaScript. This is true across all major JavaScript execution engines by up to 2x for an 8MB file, as demonstrated by this parsing benchmark.
Try Json.NET, available as a Nuget package (Newtonsoft.Json) or from http://www.newtonsoft.com/json.
Json.NET can perform class-based serialization/deserialization such as you show. It also provides a generic JObject and JToken classes for cases where the format of the Json is not known or not fixed at dev time.
Here's an example loading a json object from a file.
// load file into a JObject
JObject document;
using (var fileStream = File.OpenRead(someFilePath))
using (var streamReader = new StreamReader(fileStream))
using (var jsonReader = new JsonTextReader(streamReader))
document = JObject.Load(jsonReader);
// read the JObject
var bugs = (JObject) document["bugs"];
foreach (var bugEntry in bugs)
{
var bugID = bugEntry.Key;
var bugData = (JObject) bugEntry.Value;
var comments = (JArray) bugData["comments"];
foreach (JObject comment in comments)
Debug.Print(comment["text"]);
}
Newtonsoft.Json JsonConvert can parse it as a Dictionary<String, Comments>
provided with appropriate model classes:
public class Comment
{
public int id { get; set; }
public string text { get; set; }
}
public class Comments
{
public List<Comment> comments { get; set; }
}
public class RootObject
{
public Dictionary<String, Comments> bugs { get; set; }
}
That can be checked with:
var json = "{\r\n \"bugs\" : {\r\n \"12345\" : {\r\n \"comments\" : [\r\n {\r\n \"id\" : 1,\r\n \"text\" : \"Description 1\"\r\n },\r\n {\r\n \"id\" : 2,\r\n \"text\" : \"Description 2\"\r\n }\r\n ]\r\n }\r\n }\r\n}";
Console.WriteLine(json);
var obj = JsonConvert.DeserializeObject<RootObject>(json);
Console.WriteLine(obj.bugs["12345"].comments.First().text);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With