从表达中获取父成员

时间:2012-03-19 20:10:26

标签: c# asp.net-mvc-3 lambda expression

我有一个Expression,用于从我的Model为我的视图获取项目列表。 我想要做的是ExpressionList,我可以在Expression Tree一级向后向上移动以获得父节点吗?

让我们说这是我的观点模型:

public class MyModel {
   public MyClass myClass { get; set;}
}

...

public class MyClass {
   public List<string> MyList { get; set;}
}

我有一个HtmlHelper,它按如下方式Expression向页面呈现一个列表:

public static MvcHtmlString RenderList(this HtmlHelper<TModel> html, Expression<Func<TModel, IEnumerable<TItem>>> dataExpression)
{   
     var list = dataExpression.Compile()(html.ViewData.Model);

     ...

     return MvcHtmlString.Create(...);
}

我按照以下方式打电话给我的助手:

@model MyNamespace.Models.MyModel
@Html.RenderList(m => m.myClass.MyList)

这一切都运行正常,我的问题是,我可以将给定的Expression指向List<string>并获取它的父节点(MyClass)然后针对我的{{编译它1}}得到它的价值。所以相当于这个Model

Expression

以下是我的尝试:

m => m.myClass

2 个答案:

答案 0 :(得分:4)

以下内容应该有效:

public static IHtmlString RenderList<TModel, TItem>(
    this HtmlHelper<TModel> html, 
    Expression<Func<TModel, IEnumerable<TItem>>> dataExpression
)
{
    var parentEx = ((MemberExpression)dataExpression.Body).Expression;
    var lambda = Expression.Lambda<Func<TModel, object>>(parentEx, dataExpression.Parameters[0]);
    var value = ModelMetadata.FromLambdaExpression(lambda, html.ViewData).Model;

    ...
}

显然,您应该对此代码添加最少的错误检查,为简洁起见,我在此处有意省略。

答案 1 :(得分:1)

您必须在新的lambda表达式中使用相同的参数表达式:

var lambda = Expression.Lambda<Func<MyModel, dynamic>>(exp,
    this._dataExpression.Parameters);