我有一个MVC剃刀视图,它迭代Orders集合。每个订单都有一个Customer,可以为null。
麻烦的是,在这种情况下,我得到一个空引用异常。
@foreach (var item in Model) {
<tr>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
<td>
@item.Number
</td>
<td>
@String.Format("{0:g}", item.ReceivedDate)
</td>
<td>
@item.Customer.Name
</td>
当item.Customer为null(正如您所期望的那样)时,这一定是一个简单的问题,但未能找到答案!
在没有设置ViewModel的情况下,处理此问题的最佳方法是什么?
由于 邓肯
答案 0 :(得分:7)
尝试以下方法:
<td>
@(item.Customer != null ? item.Customer.Name : "")
</td>
编辑:附上以确保它可以在Razor中使用。
答案 1 :(得分:5)
首先,如果您要使用迭代而不是foreach,则可以使用内置的html帮助器Html.DisplayFor(m => m[i].Customer.Name)
。但这有点缺点。您可能没有索引器集合属性和DisplayFor方法获取表达式参数并编译它是昂贵的。
除了它们之外,你可以创建自己的方法来更好地处理这种情况,如下所示。
public static class Utility
{
public static TValue NullSafe<T,TValue>(this T obj,Func<T,TValue> value)
{
try
{
return value(obj);
}
catch (NullReferenceException/*Exception can be better choice instead of NullReferenceException*/)
{
return default(TValue);
}
}
}
现在你可以像
一样愉快地使用它@item.NullSafe(m=>m.Customer.Name)
将NullSafe方法作为扩展或静态是你的选择。
答案 2 :(得分:4)
一个简单的if应该做的工作:
<td>
@if (item.Customer != null)
{
<text>@item.Customer.Name</text>
}
</td>
正如所说和所示,这只是一种解决方法。真正的解决方案在于定义和使用特定的视图模型。
答案 3 :(得分:2)
不确定如何构建这些对象,但另一种处理方法是使用Null对象设计模式,这将消除测试的需要,并允许您输出有意义的文本名称(“未知”,“ “,无论如何)
答案 4 :(得分:0)
@foreach (var item in Model.Where(item => item.Customer != null))