2017-02-14 12 views
2

リフレクションを使用してビューを自動生成しようとしています。 Html.DisplayForと他のヘルパーのいくつかはLambdaExpressionに由来するExpression<Func<,>>となります。私は何が起こっているのかかなり確信していますMVCのHTMLヘルパーにLambdaExpression型を使用できますか?

<tr> 
    @foreach (var pi in Model.GetType().GetProperties()) 
    { 
     <td> 
      @Html.DisplayFor(ExpressionHelpers.GetPropertyGetterLambda(pi)) 
     </td> 
    } 
</tr> 

:ここ

The type arguments for method 'DisplayExtensions.DisplayFor<TModel, TValue>(HtmlHelper<TModel>, Expression<Func<TModel, TValue>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.`

は私のマークアップです:私は手動で自分のラムダを生成し、それを渡すことができるだろうが、それはこのエラーを投げているように見えました .DisplayForはタイプを推測するために汎用タイプの引数を必要としますが、タイプを隠している LambdaExpressionを使用しています。

タイプセーフな引数を使用して実際に.DisplayForを呼び出す式をビルド/コンパイルするのが唯一の方法だと思われますが、それはあまりにも複雑に思えます。

私の目標を達成する別の方法がありますか、ヘルパーを呼び出すのではなく、結果を直接HTMLに出力するほうがよいでしょうか?

編集:リクエストごとに、ここGetPropertyGetterLambdaのためのコードは次のとおりです。

public static LambdaExpression GetPropertyGetterLambda(PropertyInfo pi, BindingTypeSafety TypeSafety) 
{ 
    if (pi.CanRead) 
    { 
     ParameterExpression entityParameter = Expression.Parameter(TypeSafety.HasFlag(BindingTypeSafety.TypeSafeEntity) ? 
      pi.ReflectedType : typeof(object)); 
     LambdaExpression lambda = Expression.Lambda(GetPropertyReadExpression(entityParameter, pi, TypeSafety), entityParameter); 
     return lambda; 
    } 
    else 
    { 
     return null; 
    } 
} 
+0

このメソッドの実装を表示できますか? –

+0

@EhsanSajjad Updated – oscilatingcretin

答えて

0

私が最初にお勧めします。このため、別の解決策があります。

@Html.DisplayForModel() 

内部DisplayForを使用して、すべてのプロパティをレンダリングします:DisplayForModelコールにループのためにあなたを変更します。 DisplayTemplatesフォルダー内のObject.cshtml(作業中のViewsフォルダーまたはSharedフォルダー内のいずれかをグローバルに適用する)を変更して、これを変更できます。

これが不十分な場合、または本当に実際にLambdaExpressionを使用したい場合は、こちらを選択してください。 DisplayFor<TModel>(LambdaExpression expression)拡張メソッドを追加する必要があります。 (これは実際にテストしていないが、これは必要なものに近いことに注意してください)。

public static IHtmlString DisplayFor<TModel>(this HtmlHelper<TModel> helper, LambdaExpression expression) 
    { 
     var wrapperClass = typeof(DisplayExtensions); 
     ///find matching DisplayFor<TModel, TProperty> method 
     var matchingMethod = wrapperClass.GetMethods() 
      .Single(c => c.IsStatic 
       && c.Name == "DisplayFor" 
       && c.GetGenericArguments().Count() == 2 
       && c.GetParameters().Count() == 2 //overloads don't have same # of parameters. This should be sufficient. 
       ).MakeGenericMethod(typeof(TModel), expression.ReturnType); //Make generic type from the TModel and the Return Type 

     //invoke the method. The result is a IHtmlString already, so just cast. 
     return (IHtmlString) matchingMethod.Invoke(null, new Object[] { helper, expression }); 
    } 
+0

あなたの2番目の解決策は、基本的に私が取り返しのつかないことですが、リフレクションを使用して、表現木で実行時に代理人を生成します。私は彼が最初に私の場合にはうまくいくとは思っていませんが、それについて知りたいと思っています。 – oscilatingcretin

+0

@ oscillatingcretinなぜ最初はうまくいかないと思いますか? –

関連する問題