get property MVC中lambda表达式的值

时间:2014-09-01 08:32:24

标签: asp.net-mvc

在像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) ??? 感谢。

2 个答案:

答案 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;