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

时间:2014-04-10 23:08:30

标签: c# asp.net-mvc razor frontend

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

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

如果我尝试这样做,会触发一个异常,说它无法将List<Derived1ViewModel>List<Derived2VIewModel>转换为List<BaseViewModel>.如果我尝试应用{{1抛出InvalidOperationException。

详细说明: [InvalidOperationException:模板只能用于字段访问,属性访问,单维数组索引或单参数自定义索引器表达式。]

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

3 个答案:

答案 0 :(得分:0)

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

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

话虽如此,请试一试:

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

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

我们可以根据您的结果来解决这个问题。

答案 1 :(得分:0)

如果您的模型是IEnumerble&lt; SomeModel&gt;

的子类

MVC会将其渲染为SomeModel,

首先,你不能施放List&lt; A&gt;列出&lt; B&gt;直接

因此要么转换为List&lt; B&gt;在视图中并使用显示(而不是DisplayFor或将显示模板的模型类型从List&lt; A&gt;更改为IEnumerable&lt; A&gt;

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

答案 2 :(得分:0)

使用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>