2011-04-26 9 views
8

Tengo una vista de navaja MVC que itera sobre una colección Orders. Cada pedido tiene un Cliente, que puede ser nulo.Cómo manejar entidades nulas secundarias en MVC Razor

Problema es que recibo una excepción de referencia nula cuando este es el caso.

@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 explota cuando item.Customer es nula (como era de esperar).

¡Esta debe ser una pregunta fácil pero no ha podido encontrar la respuesta!

¿Cuál es la mejor manera de lidiar con esto, sin configurar un ViewModel?

Gracias Duncan

Respuesta

4

Un simple si debe hacer el trabajo:

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

Esto se dice y se muestra, eso es sólo una solución temporal. La solución real consiste en definir y usar un modelo de vista específico.

7

intente lo siguiente:

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

Editar: cerrado a garantizar que funciona en la maquinilla de afeitar.

+0

Esto no funcionará dentro de una vista de maquinilla de afeitar. Si lo encierra, entonces debería. @ (item.Customer! = Null? Item.Customer.Name: "") –

+0

@ mr-grok - Gracias por su comentario. Escribí esto de memoria, pero editaré y actualizaré mi publicación para reflejar la sintaxis correcta. – Leons

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

No estoy seguro de cómo construir estos objetos, sino otra manera de manejar esto es usando el patrón de diseño objeto nulo esto eliminaría la necesidad de tener una prueba y que permitirá a la salida de texto significativo para el nombre (" ", '', lo Ninguno desconocido)

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

5

en primer lugar se puede utilizar una función de ayuda hTML Html.DisplayFor(m => m[i].Customer.Name) si desea usar para la iteración en lugar de foreach. Pero esto tiene pocas desventajas. Puede que no tenga la propiedad de recopilación del indexador y el método DisplayFor obtenga el parámetro de expresión y compílelo, que es costoso.

En lugar de ellos, puede crear su propio método que maneje este escenario mucho mejor que a continuación.

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

Ahora se puede usar como happly

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

Haciendo método NullSafe como extensión o estática es su elección.

Cuestiones relacionadas