I'm gathering data from a web API which returns a complex JSON string. This contains values of many different types, a few arrays, and some fairly deep nesting.
Currently I'm converting the string to a dynamic object like so:
dynamic dynamicObject = JsonConvert.DeserializeObject(jsonString);
Then I'm retrieving values from this object as needed and typecasting them, however this method gives a null reference exception when I attempt to retrieve an array:
int myValue = (int)dynamicObject.foo.value; // Works!
int[] myArrayOfInts = (int[])dynamicObject.bar.values; // Null
I'm not sure how to proceed as I'm fairly new to C# and ASP.net. Most of the solutions I have come across so far require the creation of small, strictly-typed classes which mirror the entire JSON structure. In my case it would be preferable to simply use a dynamic object, partly for simplicity and partly because only certain values are actually being used.
-
1Right around the part where you say "doesn't work" you should probably explain the actual behavior that isn't working for you. Is there an exception thrown? Build error? That's all you're missing from a decent --answerable-- question.clarkitect– clarkitect2014年05月20日 18:42:16 +00:00Commented May 20, 2014 at 18:42
-
The array isn't initialised; it gives a null reference exception. Sorry that wasn't clear, I'll add it to the question.Alfie Woodland– Alfie Woodland2014年05月20日 18:46:07 +00:00Commented May 20, 2014 at 18:46
2 Answers 2
When I try to run your code, I get a RuntimeBinderException: Cannot convert type 'Newtonsoft.Json.Linq.JArray' to 'int[]'
. You can do this conversion with ToObject
.
dynamic dynamicObject = JsonConvert.DeserializeObject("{\"values\": [1, 3, 4]}");
int[] myArrayOfInts = dynamicObject.values.ToObject<int[]>();
The cast to int
works because a casting conversion is defined for many types including int
, but not int[]
.
Comments
You could deserialize the array using the ToObject<type>
extension method (where type is the desired data type):
var jsonString = @"{ ""name"":""test"", ""array"": [""10"",""20"",""30"",""40""] }";
dynamic dynamicObject = JsonConvert.DeserializeObject(jsonString);
Console.WriteLine(((string)dynamicObject.name));
var items = dynamicObject.array.ToObject<int[]>();
foreach (var item in items)
{
Console.WriteLine(item);
}
The output is:
test
10
20
30
40
Another possibility would be to cast the object to JObject
and then fetch the array as a property - the retrieved object is automatically of type JToken
, which allows iteration:
var array = ((JObject)dynamicObject)["array"];
foreach (var item in array)
{
Console.WriteLine(item.ToString());
}