从可能不存在的JToken获得价值(最佳实践)

使用Json.NET检索可能不存在于C#中的JSON值的最佳做法是什么?

现在我正在处理一个返回JSON的JSON提供者,有时它包含某些键/值对,有时不会。 我一直在使用(也许不正确)这个方法来得到我的价值(获得双倍的例子):

if(null != jToken["width"]) width = double.Parse(jToken["width"].ToString()); else width = 100; 

现在工作正常,但是当它们中有很多时,这很麻烦。 我写了一个扩展方法,只有写完后才知道我是否可能是愚蠢的…无论如何,这里是扩展方法(我只包含double和string的情况,但实际上我有很多更多):

 public static T GetValue<T>(this JToken jToken, string key, T defaultValue = default(T)) { T returnValue = defaultValue; if (jToken[key] != null) { object data = null; string sData = jToken[key].ToString(); Type type = typeof(T); if (type is double) data = double.Parse(sData); else if (type is string) data = sData; if (null == data && type.IsValueType) throw new ArgumentException("Cannot parse type \"" + type.FullName + "\" from value \"" + sData + "\""); returnValue = (T)Convert.ChangeType(data, type, CultureInfo.InvariantCulture); } return returnValue; } 

这里有一个使用扩展方法的例子:

 width = jToken.GetValue<double>("width", 100); 

顺便说一句,请原谅什么可能是一个非常愚蠢的问题,因为它似乎应该有一个内置的函数…我曾尝试谷歌和Json.NET文档,但是我要么无法find解决scheme我的问题或在文档中不清楚。

这几乎是Value()的通用方法。 如果你将它与可为空的值types相结合,你可以得到你想要的行为。 运营商:

 width = jToken.Value<double?>("width") ?? 100; 

我会写如下所示的GetValue

 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; } 

通过这种方式,您不仅可以获得基本types的价值,还可以获得复杂对象的价值。 这里是一个例子

 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"); 

以下是如何检查令牌是否存在:

 if (jobject["Result"].SelectToken("Items") != null) { ... } 

它检查“结果”中是否存在“项目”。

这是一个不正常的例子,导致exception:

 if (jobject["Result"]["Items"] != null) { ... } 

你可以简单地进行types转换,它会为你做转换,例如

 var with = (double?) jToken[key] ?? 100; 

如果对象中不存在该键,它将自动返回null ,因此不需要对其进行testing。

TYPE variable = jsonbody["key"]?.Value<TYPE>() ?? DEFAULT_VALUE;

例如

bool attachMap = jsonbody["map"]?.Value<bool>() ?? false;