2009-12-17 12 views
5

Estoy tratando de crear un HTML Helper personalizado que encapsule cierta lógica de presentación porque tengo que reutilizar esta lógica varias veces en la misma página y tal vez en el futuro.¿Cómo uso el Ayudante HTML ValidationMessage de ASP.NET MVC dentro de mi propio asistente personalizado?

Si la dirección del usuario está en Norteamérica, entonces quiero que se muestren dos cuadros de texto para la entrada del número de teléfono, uno para el código de área y el otro para el resto del número. Si la dirección está fuera de Norteamérica, entonces quiero que se muestre un cuadro de texto único para el número completo.

El siguiente código funcionaba como estaba previsto para generar los cuadros de texto correctos, sin embargo, tan pronto como agregué la validación asociada a cada cuadro de texto, ahora obtengo una NullReferenceException de la llamada ToString() en ValidationMessage Helper llamada (¡ValidationMessage Helper está devolviendo un nulo!).

public static string TelephoneNumberInputListItem(this HtmlHelper helper, 
             string country, 
             string northAmericanAreaCodeFormName, 
             string northAmericanAreaCode, 
             string northAmericanRemainingNumberFormName, 
             string northAmericanRemainingNumber, 
             string internationalFullNumberFormName, 
             string internationalFullNumber) 
    { 

     //set up the error message and styling 
     object errorHtmlAttributes = new { @class = "fError" }; 
     string validationMessage = "*"; 

     object htmlAttributes; 

     //start building our list item tag which includes our telephone number 
     //input and validation controls 
     TagBuilder listItemBuilder = new TagBuilder("li"); 

     //determine based on the country specified if this should be a North 
     //American phone input form or an international one 
     if (isNorthAmericanCountry(country)) 
     { 
      //add the text input controls 
      htmlAttributes = new { size = 3, maxlength = 3 }; 
      listItemBuilder.InnerHtml = helper.TextBox(northAmericanAreaCodeFormName, northAmericanAreaCode, htmlAttributes).ToString(); 

      htmlAttributes = new { size = 7, maxlength = 7 }; 
      listItemBuilder.InnerHtml += helper.TextBox(northAmericanRemainingNumberFormName, northAmericanRemainingNumber, htmlAttributes).ToString(); 

      //Add the Validation Message controls 
      listItemBuilder.InnerHtml += helper.ValidationMessage(northAmericanAreaCodeFormName, validationMessage, errorHtmlAttributes).ToString(); 
      listItemBuilder.InnerHtml += helper.ValidationMessage(northAmericanRemainingNumberFormName, validationMessage, errorHtmlAttributes).ToString(); 
     } 
     else 
     { 
      //add the text input control 
      htmlAttributes = new { size = 15, maxlength = 15 }; 
      listItemBuilder.InnerHtml = helper.TextBox(internationalFullNumberFormName, internationalFullNumber, htmlAttributes).ToString(); 

      //Add the Validation Message control 
      listItemBuilder.InnerHtml += helper.ValidationMessage(internationalFullNumberFormName, validationMessage, errorHtmlAttributes).ToString(); 
     } 

     return listItemBuilder.ToString(TagRenderMode.Normal); 
    } 

puede usted por favor me ayude a añadir a la validación de modo que estos cuadros de texto de entrada son todavía parte de la validación general forma sucediendo en la vista llamando? Debo mencionar que poner TextBox y ValidationMessage Helper directamente en la vista funciona correctamente.

Hay mucho alboroto para usar HTML Helpers ("si hay un IF, use un ayudante" ¿alguien?), Pero ¿cómo se supone que debemos usarlos si no podemos agregar controles de validación a los controles de entrada que utilizar.

Gracias de antemano por su ayuda.

Respuesta

4

El ayudante ValidationMessage devuelve nulo si no se indica ningún error en el estado del modelo correspondiente. Ver el código actual a continuación ...

Dado que el helper ValidationMessage devuelve una cadena, no hay ninguna razón para llamar al ToString() (que es lo que está causando la excepción). Elimine los ToString y su código debería funcionar como se esperaba.

También puede eliminar sus llamadas ToString de los ayudantes de TextBox también.

public static string ValidationMessage(this HtmlHelper htmlHelper, string modelName, string validationMessage, IDictionary<string, object> htmlAttributes) { 
    if (modelName == null) { 
    throw new ArgumentNullException("modelName"); 
    } 

    if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName)) { 
    return null; 
    } 

    ModelState modelState = htmlHelper.ViewData.ModelState[modelName]; 
    ModelErrorCollection modelErrors = (modelState == null) ? null : modelState.Errors; 
    ModelError modelError = ((modelErrors == null) || (modelErrors.Count == 0)) ? null : modelErrors[0]; 

    if (modelError == null) { 
    return null; 
    } 

    TagBuilder builder = new TagBuilder("span"); 
    builder.MergeAttributes(htmlAttributes); 
    builder.MergeAttribute("class", HtmlHelper.ValidationMessageCssClassName); 
    builder.SetInnerText(String.IsNullOrEmpty(validationMessage) ? GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, modelState) : validationMessage); 

    return builder.ToString(TagRenderMode.Normal); 
} 
+0

Gracias mkedobbs por aclarar que el ValidationMessage Helper devuelve nulo cuando no hay errores en el ModelState. La eliminación de ToString() soluciona mi problema, pero la razón por la que lo tuve allí es porque los ayudantes devuelven el tipo MVCHtmlString, que no puedo convertir a una cadena mediante el casting. De alguna manera, sin embargo, la concatenación de este MVCHtmlString a otra cadena (en mi caso, usando el operador + =) lo convierte en una cadena con éxito, por lo que se resuelven los problemas. – FullOfQuestions

Cuestiones relacionadas