我正在编写表达式树来验证Json对象。这是检查是否stuff["Address"]["State"]== "NY"
var stuff = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
ParameterExpression parameterExpression = Expression.Parameter(typeof(JObject), "g");
var indexexpr = Expression.MakeIndex(parameterExpression, typeof(JObject).GetProperty("Item", new[] { typeof(string) }), new[] { Expression.Constant("Address") });
var secondlevel = Expression.MakeIndex(indexexpr, typeof(JToken).GetProperty("Item", new[] { typeof(string) }), new[] { Expression.Constant("State") });
var conversion = Expression.Convert(secondlevel, typeof(string));
var result = Expression.Equal(conversion, Expression.Constant("NY"));
var fun =Expression.Lambda<Func<JObject, bool>>(result, new[] {parameterExpression}).Compile();
var istrue = fun(stuff);
问题:对于json对象,有时索引不存在。例如,如果我对同一个对象执行stuff["Home Address"]["State"]== "NY"
,则表达式将抛出异常
问题:如何在尝试评估索引属性之前检查索引属性是否存在?
答案 0 :(得分:3)
基本上你需要的是:
(string) (stuff["Address"] != null ? stuff["Address"]["State"] : (JToken) null) == "NY"
这可以这样构建:
var stuff = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
ParameterExpression parameterExpression = Expression.Parameter(typeof(JObject), "g");
var indexexpr = Expression.MakeIndex(parameterExpression, typeof(JObject).GetProperty("Item", new[] { typeof(string) }),
new[] { Expression.Constant("Address2") });
var secondlevel = Expression.MakeIndex(indexexpr, typeof(JToken).GetProperty("Item", new[] { typeof(string) }),
new[] { Expression.Constant("State") });
// stuff["Address2"] != null
var nullCheck = Expression.NotEqual(indexexpr, Expression.Constant(null, typeof(object)));
// stuff["Address2"] != null ? stuff["Address2"]["State"] : (JToken) null
var finalExpression = Expression.Condition(nullCheck, secondlevel, Expression.Default(typeof(JToken)));
// (string) (stuff["Address2"] != null ? stuff["Address2"]["State"] : (JToken) null)
var conversion = Expression.Convert(finalExpression, typeof(string));
// final expression
var result = Expression.Equal(conversion, Expression.Constant("NY"));
var fun = Expression.Lambda<Func<JObject, bool>>(result, new[] { parameterExpression }).Compile();
var istrue = fun(stuff);