asp.net-mvc - 我可以为 MVC 的 HTML 助手使用 LambdaExpression 类型吗?

标签 asp.net-mvc lambda expression html-helper

我正在尝试使用反射来自动生成 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/

相关文章:

asp.net-mvc - Angular4 + MVC + cli + 使用从 cli 构建命令生成的 dist 文件夹进行部署

asp.net-mvc - RemoteAttribute 没有将参数传递给操作?

jQuery ajax 在asp.net mvc 中上传文件

c# - 通过 lambdas 构造 where 的表达式

java - boolean 值流,是真的吗?

c# - 修改 "dd/MM/yyyy"的正则表达式

从 token 流解析表达式

c# - CookieAuthentication cookie 在应用程序池回收后无效

pandas - UserWarning : This pattern is interpreted as a regular expression, 并且有匹配组

java - 'Comparable<T>' 应该是 'Functional interface' 吗?