我正在尝试使用反射来自动生成 View 。 Html.DisplayFor
和其他一些 helper 拿 Expression<Func<,>>
源自LambdaExpression
.似乎我可以手动生成我自己的 lambda 然后将其传递进去,但它抛出了这个错误:
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.`
这是我的标记:
<tr>
@foreach (var pi in Model.GetType().GetProperties())
{
<td>
@Html.DisplayFor(ExpressionHelpers.GetPropertyGetterLambda(pi))
</td>
}
</tr>
我很确定发生了什么事 .DisplayFor
需要通用类型参数来推断 Func<TModel, TValue>
的类型, 但我正在使用 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;
}
}
最佳答案
我首先推荐另一种解决方案。将 for 循环更改为 DisplayForModel
调用:
@Html.DisplayForModel()
这将渲染出所有属性,使用 DisplayFor
在内部。您可以通过修改 Object.cshtml
来修改它在DisplayTemplates
文件夹(在您正在使用的 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 } );
}
关于asp.net-mvc - 我可以为 MVC 的 HTML 助手使用 LambdaExpression 类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42230499/