Как я могу использовать ASP.NET MVC ValidationMessage HTML Helper внутри моего собственного пользовательского помощника? - PullRequest
5 голосов
/ 17 декабря 2009

Я пытаюсь создать собственный HTML Helper, который инкапсулирует некоторую логику представления, потому что мне приходится использовать эту логику несколько раз на одной странице и, возможно, в будущем.

Если адрес пользователя находится в Северной Америке, то я хочу, чтобы отображались два текстовых поля для ввода номера телефона, одно для кода города, а другое для оставшейся части номера. Если адрес находится за пределами Северной Америки, я хочу, чтобы отображалось одно текстовое поле для полного номера.

Следующий код работал, как и предполагалось, для вывода правильных текстовых полей, однако, как только я добавил проверку, связанную с каждым текстовым полем, я теперь получаю исключение NullReferenceException, вызванное вызовом ToString () при вызове помощника ValidationMessage (Помощник ValidationMessage возвращает ноль !!).

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

Не могли бы вы помочь мне добавить проверку, чтобы эти текстовые поля ввода все еще были частью общей проверки формы, происходящей в вызывающем представлении? Я должен отметить, что размещение TextBox и ValidationMessage Helper непосредственно в представлении работает правильно.

Существует много шума для использования HTML Helpers («если есть IF, использовать помощника»?), Но как нам их использовать, если мы не можем добавить проверочные элементы управления к используемым элементам управления вводом? .

Заранее благодарю за помощь.

1 Ответ

4 голосов
/ 17 декабря 2009

Помощник ValidationMessage возвращает ноль, если в соответствующем состоянии модели не указано ни одной ошибки. Фактический код ниже ...

Поскольку помощник ValidationMessage возвращает строку, нет причины вызывать ToString() (что и вызывает исключение). Удалите ToString, и ваш код должен работать как положено.

Вы также можете удалить вызовы ToString из помощников TextBox.

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