Как обрабатывать нулевые дочерние объекты в MVC Razor - PullRequest
8 голосов
/ 26 апреля 2011

У меня есть вид бритвы MVC, который перебирает коллекцию Orders.Каждый заказ имеет клиента, который может быть нулевым.

Проблема в том, что я получаю исключение нулевой ссылки, когда это так.

@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 взрывается, когдаitem.Customer имеет значение null (как и следовало ожидать).

Это, должно быть, простой вопрос, но он не смог найти ответ!

Какой лучший способ справиться с этим, без настройки ViewModel?

Спасибо, Дункан

Ответы [ 5 ]

7 голосов
/ 26 апреля 2011

Попробуйте следующее:

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

Редактировать: прилагается, чтобы убедиться, что он будет работать в Razor.

5 голосов
/ 30 июня 2012

Во-первых, вы можете использовать встроенный html helper Html.DisplayFor(m => m[i].Customer.Name), если бы вы использовали для итерации вместо foreach.Но у этого есть несколько недостатков.У вас может не быть свойства коллекции индексаторов, а метод 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 в качестве расширения или статического - ваш выбор.

4 голосов
/ 26 апреля 2011

Простое if должно делать эту работу:

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

Как говорится и показано, это всего лишь обходной путь.Реальное решение состоит в определении и использовании конкретной модели представления.

2 голосов
/ 26 апреля 2011

Не уверен, как вы создаете эти объекты, но другой способ справиться с этим - использовать шаблон проектирования Null Object, это избавит от необходимости иметь тест и позволит выводить значимый текст для имени («Неизвестно», « "Ничего подобного)

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

0 голосов
/ 26 апреля 2011
@foreach (var item in Model.Where(item => item.Customer != null))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...