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

时间:2009-12-17 16:46:21

标签: asp.net-mvc validation html-helper

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

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

以下代码正在按预期方式输出正确的文本框,但是,一旦我添加了与每个文本框关联的验证,我现在从ValidationMessage Helper调用的ToString()调用中抛出NullReferenceException (ValidationMessage Helper返回null !!)。

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

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

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

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

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

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

您也可以从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);
}