自定义Html.ValidationMessageFor在客户端不起作用

时间:2011-11-04 01:54:12

标签: asp.net-mvc client-side-validation

我正在研究mvc3应用程序,我创建了一个自定义validationMessage来验证一个简单的字段。这个自定义validationMessage只显示带有标题和消息的div而不是默认的span,我有:

@Html.ValidationMessageCustomFor(model => model.FirstName)

这是我自定义验证的代码:

public static MvcHtmlString ValidationCustomFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
    string propertyName = ExpressionHelper.GetExpressionText(expression);
    string name = helper.AttributeEncode(helper.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName));

    if (helper.ViewData.ModelState[name] == null ||
        helper.ViewData.ModelState[name].Errors == null ||
        helper.ViewData.ModelState[name].Errors.Count == 0)
    {
        return MvcHtmlString.Empty;
    }

    StringBuilder htmlValidation = new StringBuilder();

    htmlValidation.AppendLine("<div>");
    htmlValidation.AppendLine("<table>");
    htmlValidation.AppendLine("<tr>");
    htmlValidation.AppendLine("<td><img src='/Content/Imgages/Error.jpg'></td>");
    htmlValidation.AppendLine("</tr>");
    htmlValidation.AppendLine("<tr>");
    htmlValidation.AppendFormat("<td>{0}</td>", name);
    htmlValidation.AppendLine("</tr>");
    htmlValidation.AppendLine("<tr>");
    htmlValidation.AppendFormat("<td>{0}</td>", helper.ViewData.ModelState[name].Errors[0].ErrorMessage);
    htmlValidation.AppendLine("</tr>");
    htmlValidation.AppendLine("</table>");
    htmlValidation.AppendLine("</div>");

    return MvcHtmlString.Create(htmlValidation.ToString());

}

当我使用服务器端验证时,这很好用,但是当我激活客户端验证时,它不起作用。

默认的Html.ValidationMessageFor是可以正常使用客户端验证,但我的自定义Html.ValidationMessageCustomFor不起作用。

你能帮助我,任何想法吗?


我修改了我的自定义助手,我为span添加了“data-valmsg-for”atrib,它是代码:

 public static MvcHtmlString ValidationCustomFor2<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
    {
        string propertyName = ExpressionHelper.GetExpressionText(expression);
        string name = helper.AttributeEncode(helper.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName));

        if (helper.ViewData.ModelState[name] == null ||
            helper.ViewData.ModelState[name].Errors == null ||
            helper.ViewData.ModelState[name].Errors.Count == 0)
        {
            return MvcHtmlString.Empty;
        }

        TagBuilder tag = new TagBuilder("span");
        tag.Attributes.Add("class", "field-validation-error");
        tag.Attributes.Add("data-valmsg-for", name);
        tag.Attributes.Add("data-valmsg-replace", "true");

        var text = tag.ToString(TagRenderMode.StartTag);
        text += "<b>My custom html</b>";
        text += tag.ToString(TagRenderMode.EndTag);


        return MvcHtmlString.Create(text);

    }

但它没有出现,它看起来我应该从客户端做一些事情,但我不知道什么?有什么想法吗?

1 个答案:

答案 0 :(得分:1)

ASP.NET MVC3验证使用服务器端和客户端方法。

当您编写服务器端代码以将验证消息添加到呈现的页面时(如在您的帮助方法中),仅在请求实际发送到服务器时调用代码,而启用客户端验证时调用代码,防止将请求发送回服务器。

MVC3客户端验证的默认实现使用一种名为Unobtrusive JavaScript验证的技术,通过向页面添加一些data-属性,然后在JavaScript中查找和操作标记的元素。

要了解Unobtrusive JavaScript验证,请尝试搜索它,那里有大量资源。例如:

http://www.codeproject.com/KB/aspnet/CustomClientSideValidatio.aspx

在您的情况下,如果要指定显示验证消息的位置,则应使用data-valmsg-for属性标记HTML元素。例如:

<SPAN data-valmsg-for="id_of_the_input_to_validate"></span>

验证JavaScript将查找上述属性,并在输入无效的情况下使用验证消息填充SPAN。同样,这发生在表单的回发之前,因此从不调用显示验证消息的服务器端代码,因为验证会阻止表单提交。

以下是MVC3中包含的实际验证消息助手的代码片段:

TagBuilder builder = new TagBuilder("span"); 
...
if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled) {
    builder.MergeAttribute("data-valmsg-for", modelName); 
    builder.MergeAttribute("data-valmsg-replace", replaceValidationMessageContents.ToString().ToLowerInvariant());
} 

编辑:回复您编辑过的问题:

第一次呈现页面时,您的第一个iftrue(没有要呈现的验证错误消息),因此您返回一个空字符串。您的网页中不会包含任何data-个属性。

即使您没有任何错误消息,也应始终呈现<span data-valmsg-for="..."></span>,以便JavaScript库知道在客户端发生错误的位置。