繁体   English   中英

MVC Html.DisplayFor用于派生模型的列表

[英]MVC Html.DisplayFor for Lists of Derived Models

假设我有三个类: Derived1ViewModelDerived2ViewModelBaseViewModel ,它们是Derived1ViewModelDerived2ViewModel的超类。

我有一个DisplayTemplate,它具有一个List<BaseViewModel>作为模型,我想从使用List<Derived1ViewModel>List< Derived2ViewModel>作为模型的视图中调用此模板。

如果我尝试执行此操作,则会触发异常,说明它无法将List<Derived1ViewModel>List<Derived2VIewModel>转换为List<BaseViewModel>. 如果我尝试应用诸如@Html.DisplayFor(model=>model.Cast<BaseViewModel>.ToList(), "MyTemplate")@Html.DisplayFor(model=>model.Cast<BaseViewModel>.ToList(), "MyTemplate")则会引发InvalidOperationException。

详细信息:[InvalidOperationException:模板只能与字段访问,属性访问,一维数组索引或单参数自定义索引器表达式一起使用。

这个问题可以解决吗,还是采取另一种方法所必需?

请注意,在@Html.DisplayFor(model=>model, "MyTemplate") ,第一个参数不是Model 这是一个将在Model上求值的Expression

将模型隐式传递给MVC表达式编译器(我认为使用ViewData),并且该模型的类型仍然是您在Razor页面开始时声明的类型。 它与表达式无关。 表达式仅指示将模型作为起始参数所需的数据。

话虽如此,试一下:

@Html.DisplayFor(model=>model.Select(dm=>(BaseViewModel)dm).ToList(), "MyTemplate")

尽管我感觉您可能会遇到“ MVC表达式评估”障碍,但它只能处理特定的一组表达式。 (常量表达式,成员访问权限等)

我们可以根据您的结果得出结论。

如果您的模型是IEnumerble <SomeModel>的子类

MVC会将其呈现为SomeModel,

首先,您不能直接将List <A>强制转换为List <B>

因此,要么在视图中转换为List <B>并使用Display(代替DisplayFor,要么将显示模板的模型类型从List <A>更改为IEnumerable <A>

其次,您必须在UIHintAttribute中设置模板名称或将其作为参数传递给DisplayFor

通过使用BaseViewModel模板而不是List<BaseViewModel>解决了该问题。 这样,我可以将任何派生类型传递给模板(例如:Derived1ViewModel,Derived2ViewModel)。

例:

@*Derived1 View*@
@model List<Derived1ViewModel>
@for(var i = 0; i < Model.Count; i++)
{
    int i1 = i;
    @Html.DisplayFor(model=>model[i1], "MyTemplate")
}

@*Derived2 View*@
@model List<Derived2ViewModel>
@for(var i = 0; i < Model.Count; i++)
{
    int i1 = i;
    @Html.DisplayFor(model=>model[i1], "MyTemplate")
}

@*Template*@
@model BaseViewModel
<p>It works @Model.Name</p>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM