如何在我自己的自定义帮助程序中使用ASP.NET MVC ValidationMessage HTML Helper?

时间:2022-12-04 08:11:04

I am trying to create a custom HTML Helper that encapsulates some presentation logic because I have to reuse this logic a few times on the same page and maybe in the future.

我正在尝试创建一个自定义HTML Helper,它封装了一些表示逻辑,因为我必须在同一页面上以及将来重复使用这个逻辑几次。

If the user's address is in North America, then I want two text boxes to be displayed for the telephone number input, one for the area code and the other for the remainder of the number. If the address is outside of North America, then I want a single text box for the full number to be displayed.

如果用户的地址在北美,那么我想要为电话号码输入显示两个文本框,一个用于区号,另一个用于剩余的数字。如果地址在北美之外,那么我想要一个单独的文本框来显示完整的数字。

The following code was working as intended for outputting the correct text boxes, however, as soon as I added the validation associated with each text box, I am now getting a NullReferenceException thrown from the ToString() call on the ValidationMessage Helper call (the ValidationMessage Helper is returning a null!!).

下面的代码按预期工作输出正确的文本框,但是,一旦我添加了与每个文本框关联的验证,我现在从ValidationMessage Helper调用的ToString()调用中抛出NullReferenceException(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);
    }

Can you please help me add the validation so that these input text boxes are still part of the overall form validation happening in the calling View? I should mention that putting the TextBox and ValidationMessage Helper directly in the View works correctly.

你能否帮我添加验证,以便这些输入文本框仍然是调用View中发生的整体表单验证的一部分?我应该提一下,将TextBox和ValidationMessage Helper直接放在View中可以正常工作。

There is a lot of buzz for using HTML Helpers ("if there's an IF, use a helper" anyone?), but how are we supposed to use them if we can't add validation controls to the input controls we use.

使用HTML Helpers有很多嗡嗡声(“如果有IF,使用帮助器”任何人?),但是如果我们不能将验证控件添加到我们使用的输入控件中,我们应该如何使用它们。

Thank you in advance for your help.

预先感谢您的帮助。

1 个解决方案

#1


4  

The ValidationMessage helper returns null if there is no error indicated in the corresponding Model State. See actual code below...

如果相应的模型状态中未指示错误,则ValidationMessage帮助程序返回null。看下面的实际代码......

Since the ValidationMessage helper returns a string, there is no reason to call ToString() (which is what is causing the exception). Remove the ToString's and your code should work as expected.

由于ValidationMessage助手返回一个字符串,因此没有理由调用ToString()(导致异常的原因)。删除ToString,您的代码应该按预期工作。

You can also remove your ToString calls from the TextBox helpers as well.

您也可以从TextBox助手中删除ToString调用。

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

#1


4  

The ValidationMessage helper returns null if there is no error indicated in the corresponding Model State. See actual code below...

如果相应的模型状态中未指示错误,则ValidationMessage帮助程序返回null。看下面的实际代码......

Since the ValidationMessage helper returns a string, there is no reason to call ToString() (which is what is causing the exception). Remove the ToString's and your code should work as expected.

由于ValidationMessage助手返回一个字符串,因此没有理由调用ToString()(导致异常的原因)。删除ToString,您的代码应该按预期工作。

You can also remove your ToString calls from the TextBox helpers as well.

您也可以从TextBox助手中删除ToString调用。

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