Asp.net mvc 获取MVC中lambda表达式的propertyValue
在像Asp.net mvc 获取MVC中lambda表达式的propertyValue,asp.net-mvc,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).ToSt
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
???
谢谢。您似乎想要嵌套类型,请尝试这样做
在这种情况下,您需要的是一个可执行表达式,它将访问属性的包含对象(例如,获取源对象的Docs属性或源对象的Docs属性的Customer属性)。您还需要目标属性的PropertyInfo(例如ID)。您希望属性访问器和属性信息来自同一个表达式
这并不太难。它不需要像最初担心的那样有一堆目标对象和属性。首先以正常方式存储嵌套目标的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);
}
}
}
关键行是包含表达式.Lambda()的行。父表达式是MemberExpression(例如model.Docs.Customer),它本身是不可执行的。您不能编译MemberExpression并在对象上执行它来获取成员,因为表达式需要知道它所针对的参数
表达式。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;
}
ModelMetadata包含一个属性对象模型
,可用于获取模型的值
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var value = metaData.Model;