我正在尝试使用反射来自动生成视图。 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();// New feature
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
以及其他一些帮助者从Html.DisplayFor
获取Expression<Func<,>>
。看起来像我能够手动生成我自己的lambda,然后将其传入,但它会抛出此错误:
方法的类型参数&#39; DisplayExtensions.DisplayFor&lt; TModel,TValue&gt;(HtmlHelper&lt; TModel&gt;,Expression&lt; Func&lt; TModel,TValue&gt;&gt;)&#39;无法从使用中推断出来。尝试明确指定类型参数。
这是我的标记:
LambdaExpression
我很确定发生了什么<tr>
@foreach (var pi in Model.GetType().GetProperties())
{
<td>
@Html.DisplayFor(ExpressionHelpers.GetPropertyGetterLambda(pi))
</td>
}
</tr>
需要泛型类型参数来推断.DisplayFor
的类型,但我使用隐藏类型的Func<TModel, TValue>
。
似乎做我想要的唯一方法是构建/编译一个实际使用类型安全参数调用LambdaExpression
的表达式,但这似乎过于复杂。
是否有其他方法可以实现我的目标,或者我最好只将结果直接输出到HTML而不是调用助手?
修改:根据请求,这里是.DisplayFor
的代码:
GetPropertyGetterLambda
答案 0 :(得分:0)
首先我推荐另一个解决方案。将您的for循环更改为DisplayForModel
来电:
@Html.DisplayForModel()
这将在内部使用DisplayFor
呈现所有属性。您可以通过修改Object.cshtml
文件夹中的DisplayTemplates
(在您正在使用的Views
文件夹中,或在Shared
文件夹中全局应用)来修改此项。< / p>
如果这还不够,或者你真的想使用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 } );
}