2009-12-17 6 views
5

Ich versuche, einen benutzerdefinierten HTML-Helfer zu erstellen, der einige Präsentationslogik einkapselt, weil ich diese Logik ein paar Mal auf derselben Seite und vielleicht in der Zukunft wiederverwenden muss.Wie verwende ich den ASP.NET MVC ValidationMessage-HTML-Helfer in meinem eigenen benutzerdefinierten Helfer?

Wenn die Adresse des Benutzers in Nordamerika ist, möchte ich zwei Textfelder für die Telefonnummer eingeben, eine für die Vorwahl und die andere für den Rest der Nummer. Wenn die Adresse außerhalb von Nordamerika liegt, möchte ich ein einzelnes Textfeld für die vollständige Nummer anzeigen.

Der folgende Code funktionierte wie vorgesehen für die Ausgabe der richtigen Textfelder, aber sobald ich die Validierung für jedes Textfeld hinzugefügt habe, erhalte ich jetzt eine NullReferenceException, die vom ToString() -Aufruf des ValidationMessage-Helpers ausgelöst wird call (der ValidationMessage Helper gibt eine Null zurück !!).

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

Können Sie mir bitte helfen, die Validierung hinzufügen, so dass diese Eingabetextfelder in der Aufruf-Ansicht immer noch geschieht Teil der Gesamtformularvalidierung sind? Ich sollte erwähnen, dass die TextBox und ValidationMessage Helper direkt in der Ansicht richtig funktioniert.

Es gibt eine Menge Buzz für die Verwendung von HTML-Helfern ("Wenn es ein IF gibt, verwenden Sie einen Helfer"), aber wie sollen wir sie verwenden, wenn wir keine Validierungssteuerelemente zu den Eingabesteuerelementen hinzufügen können benutzen.

Vielen Dank im Voraus für Ihre Hilfe.

Antwort

4

Der Helper ValidationMessage gibt null zurück, wenn im entsprechenden Modellstatus kein Fehler angezeigt wird. Siehe tatsächlichen Code unten ...

Da der ValidationMessage-Helper eine Zeichenfolge zurückgibt, gibt es keinen Grund, ToString() aufzurufen (was die Ausnahme verursacht). Entfernen Sie die ToString und Ihr Code sollte wie erwartet funktionieren.

Sie können Ihre ToString-Aufrufe auch von den TextBox-Helfern entfernen.

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

Vielen Dank mkedobbs für die Klärung, dass der ValidationMessage Helper Null zurückgibt, wenn keine Fehler in ModelState vorliegen. Das Entfernen des ToString() beseitigt mein Problem, aber der Grund, warum ich es an erster Stelle hatte, ist, weil die Helfer den Typ MVCHtmlString zurückgeben, den ich nicht durch Casting in einen String konvertieren kann. Irgendwie konvertiert diese MVCHtmlString zu einer anderen Zeichenfolge (in meinem Fall mit dem + = -Operator) konvertiert es in eine Zeichenfolge erfolgreich, so Problem (s) gelöst. – FullOfQuestions