What\'s the best practice for retrieving JSON values that may not even exist in C# using Json.NET?
Right now I\'m dealing with a JSON provider that returns JSON that
Here is how you can check if the token exists:
if (jobject["Result"].SelectToken("Items") != null) { ... }
It checks if "Items" exists in "Result".
This is a NOT working example that causes exception:
if (jobject["Result"]["Items"] != null) { ... }
This takes care of nulls
var body = JObject.Parse("anyjsonString");
body?.SelectToken("path-string-prop")?.ToString();
body?.SelectToken("path-double-prop")?.ToObject<double>();
This is pretty much what the generic method Value() is for. You get exactly the behavior you want if you combine it with nullable value types and the ??
operator:
width = jToken.Value<double?>("width") ?? 100;
I would write GetValue
as below
public static T GetValue<T>(this JToken jToken, string key, T defaultValue = default(T))
{
dynamic ret = jToken[key];
if (ret == null) return defaultValue;
if (ret is JObject) return JsonConvert.DeserializeObject<T>(ret.ToString());
return (T)ret;
}
This way you can get the value of not only the basic types but also complex objects. Here is a sample
public class ClassA
{
public int I;
public double D;
public ClassB ClassB;
}
public class ClassB
{
public int I;
public string S;
}
var jt = JToken.Parse("{ I:1, D:3.5, ClassB:{I:2, S:'test'} }");
int i1 = jt.GetValue<int>("I");
double d1 = jt.GetValue<double>("D");
ClassB b = jt.GetValue<ClassB>("ClassB");
You can simply typecast, and it will do the conversion for you, e.g.
var with = (double?) jToken[key] ?? 100;
It will automatically return null
if said key is not present in the object, so there's no need to test for it.
TYPE variable = jsonbody["key"]?.Value<TYPE>() ?? DEFAULT_VALUE;
e.g.
bool attachMap = jsonbody["map"]?.Value<bool>() ?? false;