2009-05-05 10 views
8

tengo el siguiente código en una vista inflexible de tipos en mi solicitud:NullReferenceException problema con ASP.NET MVC cuadro de texto HtmlHelper

<td> 
<label for="TriageStartDate">Triage Start:</label> 
<%= Html.TextBox("TriageStartDate", crit.TriageStartDate, new { maxlength = 10, size = 12 })%> 
<%= Html.ValidationMessage("TriageStartDate", "*") %> 
</td> 

La variable crit se pasa en ViewData y se echó a un strongly- mecanografiado objeto en la vista usando:

PatientSearchCriteria crit = (PatientSearchCriteria)ViewData["criteria"];  

el TriageStartDate propiedad es una propiedad de cadena definido en el objeto de esta manera:

public string TriageStartDate { get; set; } 

Tengo una rutina de validación en el objeto comercial que marca esta propiedad para fechas no válidas. La rutina de validación se llama en mi controlador, y en el controlador agrego un ModelError al ModelState cuando se encuentra una fecha no válida (por ejemplo, "4/34/2009"). Esto debería ocasionar que la vista se vuelva a mostrar y que también se muestren el resumen y el mensaje de validación.

Sin embargo, el código se bloquea en la línea Html.TextBox con una NullReferenceException no controlada. El código solo se bloquea cuando se ingresan fechas no válidas, lo que probablemente no debería importar ya que la propiedad es una cadena de todos modos, y solo debe mostrar la fecha no válida en el cuadro de texto.

¿Alguna idea de lo que puede estar pasando aquí? Pensé que podría ser algo de HTML.Encode, pero las fechas válidas se muestran sin problemas. Cuando rompo esa línea en modo de depuración, puedo ver el valor "4/34/2009" en la propiedad TriageStartDate, y la variable crit en sí misma no es nula, entonces me pregunto qué objeto ES nulo.

Por cierto, las primeras líneas de la traza de la pila tener este aspecto:

[NullReferenceException: Object reference not set to an instance of an object.] 
    System.Web.Mvc.HtmlHelper.GetModelStateValue(String key, Type destinationType) +63 
    System.Web.Mvc.Html.InputExtensions.InputHelper(HtmlHelper htmlHelper, InputType inputType, String name, Object value, Boolean useViewData, Boolean isChecked, Boolean setId, Boolean isExplicitValue, IDictionary`2 htmlAttributes) +519 
    System.Web.Mvc.Html.InputExtensions.TextBox(HtmlHelper htmlHelper, String name, Object value, IDictionary`2 htmlAttributes) +34 
    System.Web.Mvc.Html.InputExtensions.TextBox(HtmlHelper htmlHelper, String name, Object value, Object htmlAttributes) +62 

Aquí está mi código de validación (que podría no ser bastante). En el objeto de negocio:

public override IEnumerable<ValidationError> GetValidationErrors() 
{ 
    // check for valid start date 
    if (!String.IsNullOrEmpty(TriageStartDate)) 
    { 
     DateTime critStartDate; 
     if (!DateTime.TryParse(TriageStartDate, out critStartDate)) 
      yield return new ValidationError(String.Format("Invalid triage start date specified: {0}", TriageStartDate), "TriageStartDate"); 
    } 

    // check for valid end date 
    if (!String.IsNullOrEmpty(TriageEndDate)) 
    { 
     DateTime critEndDate; 
     if (!DateTime.TryParse(TriageEndDate, out critEndDate)) 
      yield return new ValidationError(String.Format("Invalid triage end date specified: {0}", TriageEndDate), "TriageEndDate"); 
    } 

    // verify that end date follows start date if both are specified 
    if (!String.IsNullOrEmpty(TriageStartDate) && !String.IsNullOrEmpty(TriageEndDate)) 
    { 
     DateTime startDate; 
     DateTime endDate; 

     if (DateTime.TryParse(TriageStartDate, out startDate) && DateTime.TryParse(TriageEndDate, out endDate)) 
     { 
      if (startDate > endDate) 
       yield return new ValidationError("Triage start date must be before end date", "_FORM"); 
     } 
    } 

    yield break; 
} 

en el controlador:

// validate search criteria 
    if (!criteria.IsValid) 
    { 
     foreach (ValidationError ve in criteria.GetValidationErrors()) 
     { 
      ModelState.AddModelError(ve.PropertyName, ve.ErrorMessage); 
     } 
    } 

Gracias por cualquier pista!


Gracias a las sugerencias de Craig, actualicé el código del controlador de la siguiente manera, y la excepción de referencia nula desapareció. La solución funcionó, pero no estoy seguro de entender el razonamiento, ya que el valor que el usuario intentó ingresar ya está almacenado en el objeto modelo, y tengo otras vistas y controladores en el proyecto que muestran errores de validación de la misma manera sin cualquier problema. Pero, bueno, si funciona ...

// validate search criteria 
    if (!criteria.IsValid) 
    { 
     foreach (ValidationError ve in criteria.GetValidationErrors()) 
     { 
      ModelState.AddModelError(ve.PropertyName, ve.ErrorMessage); 
      ModelState.SetModelValue(ve.PropertyName, form.ToValueProvider()[ve.PropertyName]); 
     } 

    } 
+0

poner el código de validación, creo que el problema es que hay –

Respuesta

9

Después de llamar AddModelError que necesita para llamar SetModelValue. Eso debería arreglar la referencia nula.

+0

Craig, gracias por la respuesta, pero no puedo encontrar ningún método SetAttempedValue en cualquiera de los objetos en el controlador o la vista. Veo SetModelValue, pero no tengo claro cómo usar esto, o incluso si debería, dado el segundo parámetro de tipo ValueProviderResult, que no sé cómo construir. El modelo realmente contiene el intento de valor introducido por el usuario, por lo que no estoy seguro de dónde me deja. Tal vez en las profundidades, en alguna parte, ASP.NET MVC está tratando de convertir el valor en una fecha y tener un problema. –

+0

Una forma es con Form.ToValueProvider() ... –

+0

Gracias, Craig. Actualicé mi código para contener SetModelValue con el método Form.ToValueProvider generando ValueProviderResult, y esto solucionó la excepción de referencia nula. Todavía estoy confundido, pero mi código funciona ... :-) –

1

Me encontré con esto ya que estaba escribiendo una pregunta/problema casi idéntico. (es decir, renderizar mi vista provocaba que se lanzara una misteriosa NullReferenceException cuando valía el valor del usuario en un campo en particular.

Una solución alternativa diferente que he encontrado genera explícitamente el Html en la vista en lugar de dejando que el HtmlHelper haga el trabajo.

Por ejemplo: <%= Html.TextArea("FieldName", Model.FieldName) %> sería una excepción, pero <textarea id="FieldName" name="FieldName"><%= Model.FieldName ></textarea> funcionaría perfectamente bien.

Gracias por publicar la pregunta original ya que ahora voy a tener que hacer algo más buscando en SetModelValue para ver cuál de los dos enfoques es la mejor solución ...

Cuestiones relacionadas