I wrote the following method to convert JToken to good old conventional .NET types.
This is more thorough than I need (to handle only a few JTokenTypes), but I extended it for this answer.
Caveat discipulus: This code is untested and may be a poor implementation of the worst possible approach to a problem that doesn't exist.
/// <summary>Converts a Json.Net JToken to a boxed conventional .NET type (int, List, etc.)</summary>
/// <param name="token">The JToken to evaluate</param>
public object JTokenToConventionalDotNetObject(JToken token)
{
switch(token.Type) {
case JTokenType.Object:
return ((JObject)token).Properties()
.ToDictionary(prop => prop.Name, prop => JTokenToConventionalDotNetObject(prop.Value));
case JTokenType.Array:
return token.Values().Select(JTokenToConventionalDotNetObject).ToList();
default:
return token.ToObject<object>();
}
}
To handle JArrays, my original problem, Json.NET again makes the task simple:
/// <summary>Converts a Json.NET JArray into a List of T where T is a conventional .NET type (int, string, etc.)</summary>
/// <param name="jArray">Json.NET JArray to convert</param>
public IList<object> JArrayToList(JArray jArray) {
return (List<object>)jArray.ToObject(typeof(IList));
}
Input type: JArray
of Newtonsoft.Json.Linq.JValue
with JTokenType
of Integer
Output: List<object>
where each object is of type System.Int64
I believe that Json.NET's ToObject
behavior is not always obvious. Given conversion type <Object>
, it returns either a conventional .NET type (long
, string
) or does nothing at all, e.g. gets and returns Newtonsoft.Json.Linq.JArray
, depending on the JTokenType.
Edit: Simplified code with @mason's help and with code from the SO question for which mine is marked duplicate. Now that I better understand Json.NET's types work, I see that answer was sufficient.
The salient difference between the answers is only that that this code handles nested arrays/objects.