Get value from JToken that may not exist (best practices)
使用Json.NET检索C#中甚至可能不存在的JSON值的最佳实践是什么?
现在我正在处理一个JSON提供程序,它返回有时包含某些键/值对的JSON,有时则不然。我一直在使用(也许是错误的)这个方法来获取我的值(例如获得一个double):
1 2 3 4 | if(null != jToken["width"]) width = double.Parse(jToken["width"].ToString()); else width = 100; |
现在它工作正常,但是当它们很多时它很麻烦。我最后编写了一个扩展方法,并且只有在写完之后我才会想知道是否我是傻...反正这里是扩展方法(我只包括双和字符串的情况,但实际上我有很多更多):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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; } |
这是使用扩展方法的示例:
1 | width = jToken.GetValue<double>("width", 100); |
顺便说一句,请原谅可能是一个非常愚蠢的问题,因为它似乎应该有一个内置函数...我确实尝试了谷歌和Json.NET文档,但是我要么找不到解决方案我的问题或在文档中不清楚。
这几乎是泛型方法
1 | width = jToken.Value<double?>("width") ?? 100; |
我会写
1 2 3 4 5 6 7 | 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; } |
这样,您不仅可以获得基本类型的值,还可以获得复杂对象的值。 这是一个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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"); |
以下是检查令牌是否存在的方法:
1 | if (jobject["Result"].SelectToken("Items") != null) { ... } |
它检查"结果"中是否存在"项目"。
这是一个导致异常的非工作示例:
1 | if (jobject["Result"]["Items"] != null) { ... } |
您可以简单地进行类型转换,它会为您进行转换,例如:
1 | var with = (double?) jToken[key] ?? 100; |
如果对象中不存在所述键,它将自动返回
这会处理空值
1 2 3 4 5 | var body = JObject.Parse("anyjsonString"); body?.SelectToken("path-string-prop")?.ToString(); body?.SelectToken("path-double-prop")?.ToObject<double>(); |
例如