MVC Html.衍生模型列表的DisplayFor



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

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

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

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

这个问题能解决吗?还是有必要采取另一种方法?

请注意,在@Html.DisplayFor(model=>model, "MyTemplate")中,第一个参数不是模型。它是一个Expression,将在模型上进行评估。

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

话虽如此,试试看:

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

尽管我有一种感觉,你可能会遇到MVC表达式求值的障碍,它只能处理一组特定的表达式。(常量表达式、成员访问等)

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

如果您的模型是IEnumerable<SomeModel>

MVC将把它呈现为SomeModel,

首先,您不能强制列表<A>到列表<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>

相关内容

  • 没有找到相关文章

最新更新