我正在研究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);
}
但它没有出现,它看起来我应该从客户端做一些事情,但我不知道什么?有什么想法吗?
答案 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());
}
编辑:回复您编辑过的问题:
第一次呈现页面时,您的第一个if
是true
(没有要呈现的验证错误消息),因此您返回一个空字符串。您的网页中不会包含任何data-
个属性。
即使您没有任何错误消息,也应始终呈现<span data-valmsg-for="..."></span>
,以便JavaScript库知道在客户端发生错误的位置。