2012-03-19 5 views
4

私はExpressionを持っています。これは私のビューのために私のModelからアイテムのリストを取得するために使用されます。 私は何をしたいのですか、ListExpressionが与えられていますが、Expression Treeの親ノードを取得するために上に戻ることができますか?式から親メンバーを取得

:私は、ページにリストをレンダリングするために、次のように Expressionを取る HtmlHelperを持っている...

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

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

を:

のは、これが私の見解モデルであるとしましょう

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) 

このすべては、私はそれが親ノード(MyClass)、それは価値だ得るために、私Modelに対してそれをコンパイルしますList<string>を指す与えExpressionを取ると、取得することができ、私の質問があり、正常に動作します。したがって、このExpressionの同等:ここ

m => m.myClass 

は、私が試したものです:

// This gets the correct expression 
var exp = ((MemberExpression)this._dataExpression.Body).Expression; 
// Create a parameter representing the type of the Model ? 
var parameter = Expression.Parameter(typeof(TModel)); 
// Create lambda 
var lambda = Expression.Lambda<Func<TModel, dynamic>>(exp, parameter); 
// Try and compile against the view model 
var obj = lambda.Compile()(html.ViewData.Model); 

答えて

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; 

    ... 
} 

もちろん、あなたがこれにエラーチェックの最小値を追加する必要がありますここでは簡潔にするために意図的に省略したコードです。

+0

は完全に働いたこと、ありがとうございました。 – Gabe

1

あなたの新しいラムダ式で同じパラメータ表現を使用する必要があります。

var lambda = Expression.Lambda<Func<MyModel, dynamic>>(exp, 
    this._dataExpression.Parameters); 
関連する問題