开发者

How to handle null child Entities in MVC Razor

I have an MVC razor view that iterates over an Orders collection. Each order has a Customer, which can be null.

Trouble is, I get 开发者_Go百科a null reference exception when this is the case.

@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.Name blows up when item.Customer is null (as you'd expect).

This must be an easy question but haven't been able to find the answer!

What's the best way to deal with this, without setting up a ViewModel ?

Thanks Duncan


Try the following:

<td>        
    @(item.Customer != null ? item.Customer.Name : "")
</td>

Edit: Enclosed to ensure it will work in Razor.


Firstly you can use built-in html helper Html.DisplayFor(m => m[i].Customer.Name) if you would using for iteration instead of foreach. But this have few downside. You may not have indexer collection property and DisplayFor method get expression parameter and compile it which is costly.

Instead of them you can create your own method that handles this scenario much betterly like below.

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);
        }
    }
}

Now you can use it happly like

@item.NullSafe(m=>m.Customer.Name)

Making NullSafe method as extension or static is your choice.


A simple if should do the job:

<td>
    @if (item.Customer != null)
    {
        <text>@item.Customer.Name</text>
    }
</td>

This being said and shown, that's only a workaround. The real solution consists in defining and using a specific view model.


Not sure how you build up these objects but another way of handling this is by using the Null Object design pattern this would remove the need to have a test and allow you to output meaningful text for the name ("Unknown", "",None whatever)

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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜