在像model =>model.ID
之类的简单lambda表达式中,我可以用这种方式获得propertyValue
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var propertyName = metaData.PropertyName;
var propertyValue = htmlHelper.ViewData.Eval(propertyName).ToStringOrEmpty();
但是如何从此表达式model => model.Docs.Customer.ID
中获取值(ID)
???
感谢。
答案 0 :(得分:0)
似乎你想要嵌套类型,试着这样做。
在这种情况下,您需要的是一个可执行表达式,它将访问属性的包含对象(例如,获取源对象的Docs属性或源对象的Docs属性的Customer属性)。您还需要目标属性的PropertyInfo(例如ID)。并且您希望属性访问器和PropertyInfo都来自同一个表达式。
这并不太难。它不需要一堆目标对象和最初担心的PropertyInfos。首先以正常方式从嵌套目标存储PropertyInfo:
targetPropertyInfo = targetExpression.AsPropertyInfo();
这使我们可以访问ID。然后存储表达式,该表达式从原始源 - .Docs或.Customer.ID中检索属性的包含对象的路径。在表达式树中,这是包含原始参数的根的表达式:
if (targetExpression.Body.NodeType == ExpressionType.MemberAccess)
{
MemberExpression memberExpression = targetExpression.Body as MemberExpression;
if (memberExpression.Expression.NodeType != ExpressionType.Parameter)
{
ParameterExpression parameter = GetParameterExpression(memberExpression.Expression);
if (parameter != null)
{
_targetExpression = Expression.Lambda(memberExpression.Expression, parameter);
}
}
}
关键行是包含Expression.Lambda()的键。父表达式是一个MemberExpression(例如model.Docs.Customer),它本身不可执行。您无法编译MemberExpression并在对象上执行它以获取该成员,因为表达式需要知道它执行的参数。
Expression.Lambda针对提供的目标参数创建一个可编译的可执行表达式 - 我们已经从原始表达式的“模型”中获取了该表达式,我们可以找到任何级别的嵌套:
private ParameterExpression GetParameterExpression(Expression expression)
{
while (expression.NodeType == ExpressionType.MemberAccess)
{
expression = ((MemberExpression)expression).Expression;
}
if (expression.NodeType == ExpressionType.Parameter)
{
return (ParameterExpression)expression;
}
return null;
}
答案 1 :(得分:0)
ModelMetadata包含一个属性object Model
,可用于获取模型的值。
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var value = metaData.Model;