0

我有一个 ViewModel 扩展了一个众所周知的基类,以允许共享视图读取公共属性。这是设计使然。

我还有一些页面显示模型中包含的实体列表的详细信息。以下代码提供了一个示例:

public abstract class AbstractViewModel {
      public Exception lastError; //If not null triggers a big warning
}

public class Cat{
      [Display(...)]
      public string Name;
}

public class CatListViewModel: AbstractViewModel {
      public IEnumerable<Cat> cats;
}

现在我的局部视图需要使用常见的 MVC 方式显示猫的列表

@model Org.Zighinetto.CatListViewModel

<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Cats.Name) //Doesn't work!!
        </th>
    </tr>
    @foreach (var item in Model.Cats)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
        </tr>
    }
</table>

不幸的是,我不能使用DisplayNameFor集合作为参数

问题是

IEnumerable<Cat>鉴于上述数据模型,并且鉴于设计原因我不想将模型性质更改为...

当表达式涉及集合时,尤其是当该集合为空时,如何将作为Cat类的属性的显示名称绑定到方法或任何等效项?DisplayNameFor否则问,如何修复上述编译错误?DisplayNameFor在这种情况下,正确的语法是什么?

4

2 回答 2

0

自己运气好发现的。

基本上Html.DisplayNameFor(Model => Model.Cats.FirstOrDefault().Name)可以工作,因为即使没有猫,运行时也会Cat正确反映类型

于 2013-03-28T23:36:49.690 回答
0

您需要在代码中注意几件事以防止出现空异常。

首先,您需要初始化您Cats的集合,以便当您的代码没有这样做时,出于正当的原因并且它在现实中发生,您可以避免出现空异常。所以你可以这样写你的模型:

public class CatListViewModel: AbstractViewModel {
    public CatListViewModel() {
        Cats = new List<Cat>();
    }
    public IEnumerable<Cat> Cats;
}

因此,在您看来,如果您这样做,Model.Cats.FirstOrDefault()您将不会得到空异常,因为Cats它是空的。

其次,既然您“可以”拥有一个空集合(空),因为您在CatListViewModel创建实例时正在对其进行初始化,所以您仍然可能遇到空异常。NULL那是因为您告诉编译器在列表中没有项目时给您- Model.Cats.FirstOrDefault()。所以你需要做的是:

<th>
    @if (Model.Cats.Any()) {
        @Html.DisplayNameFor(model => model.Cats.First().Name)
    }
</th>
于 2013-03-29T05:20:01.400 回答