2012-03-01 9 views
6

Demasiado a menudo me he encontrado con una situación en la que una vista en mi proyecto arroja una excepción de referencia nula .Vistas MVC3: Manejo de modelos nulos con finesse

@model Johnny.Application.TestModel 
<div>@(Model.SomeText)</div> 

Esto arroja un error si Modelo es nula .

Pero, ¿cómo está la gente manejando esto? Ciertamente no veo ejemplos de códigos en todas partes con feos chequeos nulos que ensucian el código en la vista. Eso me lleva a creer que la mayoría de las veces, los controladores no deben devolver modelos nulos. Pero, ¿cómo puedes hacer cumplir esto con más delicadeza?

En este momento tan pronto como alguien hace accidentalmente que un controlador devuelva un modelo nulo, el modelo de vista explota y parece fallar. En realidad, fue culpa del controlador. Y la vista puede que ni siquiera "capte" el problema, solo lo hará si los miembros del modelo se acostumbran (lo cual es la mayoría de las veces, por supuesto).

Por varias razones, algunas vistas pueden querer manejar valores nulos. Sin embargo, no esperaría que este fuera el caso de la mayoría. Claramente, esta es la cuestión de establecer algún "contrato" entre la vista y el controlador.

No me gustan las opciones que he visto:

  1. Comprobar si el modelo es nulo cada vez que se usa. Muy cojo!
  2. Uno grande si la declaración ajusta toda la vista con un modelo nulo check. Piensa en el código desperdiciado de bienes raíces. ¡Cojo!
  3. Agregue si lo controla con un tiro en la parte superior. No está mal, pero parece tonto. Levemente cojo

Me gustaría saber si algo así existiera estas opciones para configurar el "no nulos" contrato:

  • Un atributo del método de controlador como [NoNullModels]. Dudo que esto exista, ya que no creo que el controlador sepa a qué vista se está conectando.
  • En la vista, como un indicador @ MVC3.HeyDontAllowNulls o alguna otra forma estándar de lanzar una excepción (como opción 3 anterior)
+0

¿por qué incluso devolvería un modelo nulo? –

+1

ha intentado '@ Html.DisplayFor (m => m.SomeText)' –

+0

En el tema de muestra de código, el 99% de los ejemplos de código en Internet carecen de manejo de excepción y validación de entrada. En parte por holgazanería y en parte porque confundiría el punto que la muestra del código está ilustrando. –

Respuesta

2

me hizo una pregunta similar aquí Should one try to guard against null reference exceptions/index out of bounds exceptions in MVC views? y tiene una buena respuesta a la misma. En resumen, se prefiere agregar comprobaciones nulas en sus controladores y quizás incluso pruebas de unidades en lugar de sus puntos de vista.

+0

No había pensado en el enfoque de pruebas unitarias, y este es un buen escenario para su utilidad. Dado que no "poseo" todo el código, no podré hacer que todos los controladores se puedan probar con la unidad, por lo que espero encontrar una opción alternativa para la vista en estos casos. –

+0

También admito que si tuviera, por ejemplo, una vista muy compartida que se renderizara a partir de numerosos métodos de acción, estaría tentado de agregar una verificación nula en un lugar, en la vista, en lugar de en una docena de lugares más. incluso si poseyera todo el código. Es posible que pueda llamar eso una adherencia al principio DRY a costa de violar la Separación de Preocupaciones MVC un poco. –

+0

Cuanto más lo pienso, más siento que la vista es el lugar correcto para agregar algo. Una razón es que una sola acción de controlador puede enrutar a varias vistas diferentes. Arreglarlo en el lado del controlador no es efectivo, ya que tarde o temprano saltará una fuga (¡como la situación en la que me sigo topando!) –

0

Hay muchas preferencias aquí, algunos que se pueden hacer son: RecordNotFoundException

  1. lanzar en su capa de datos (excepción personalizada) y tiene una captura mundial de filtro de excepción de este
  2. Compruebe si hay valores nulos que regresan de su repositorio y maneje en un escenario caso por caso
  3. Decore sus controladores para buscar un modelo nulo en métodos GET que no sean métodos CREATE (o las reglas que considere correctas) con un atributo de filtro de acción para verificar esto en OnActionExecuted

Incluso mis vistas "CREATE" generalmente obtienen un modelo, incluso si están vacías (aunque con frecuencia tienen un IEnumerable <SelectListItem> en ellas), por lo que siempre deberían tener un modelo para ellas.

0

Compruebo null en mis vistas a veces en partes que lo requieren.

A veces crearé valores predeterminados en mi controlador si va a haber un valor nulo depende de lo que está intentando hacer y de lo que es aceptable.

Tengo, por ejemplo, un caso en el que las personas se suscriben a algo y configuran las notificaciones. Si no tienen notificaciones, un subobjeto de mi modelo es nulo. No quiero establecer los valores predeterminados, así que tengo una marca allí. En otras secciones solo uso un valor predeterminado.

Cuestiones relacionadas