如何在MVC Razor中处理null子实体

时间:2011-04-26 17:56:05

标签: asp.net entity-framework asp.net-mvc-3 razor

我有一个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(正如您所期望的那样)时, @ item.Customer.Name会爆炸。

这一定是一个简单的问题,但未能找到答案!

在没有设置ViewModel的情况下,处理此问题的最佳方法是什么?

由于 邓肯

5 个答案:

答案 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对象设计模式,这将消除测试的需要,并允许您输出有意义的文本名称(“未知”,“ “,无论如何)

http://sourcemaking.com/refactoring/introduce-null-object

答案 4 :(得分:0)

@foreach (var item in Model.Where(item => item.Customer != null))