我将 ASP.NET MVC3 用于具有服务器和客户端验证的表单。我将错误消息显示为输入上方的气球。由于错误的显示,我一次只需要显示一个错误,否则气球往往会掩盖其他可能也有错误的字段。
如何自定义验证行为以仅呈现第一条错误消息?
编辑:请注意表单同时具有服务器和客户端验证,并且我只想显示整个表单(而不是每个字段)的第一条错误消息。
我将 ASP.NET MVC3 用于具有服务器和客户端验证的表单。我将错误消息显示为输入上方的气球。由于错误的显示,我一次只需要显示一个错误,否则气球往往会掩盖其他可能也有错误的字段。
如何自定义验证行为以仅呈现第一条错误消息?
编辑:请注意表单同时具有服务器和客户端验证,并且我只想显示整个表单(而不是每个字段)的第一条错误消息。
如果有人需要,我想出的解决方案是在页面底部添加以下脚本。这与现有的 javascript 验证挂钩,以动态隐藏表单中除第一个错误之外的所有错误。
<script>
$(function() {
var form = $('form')[0];
var settings = $.data(form, 'validator').settings;
var errorPlacementFunction = settings.errorPlacement;
var successFunction = settings.success;
settings.errorPlacement = function(error, inputElement) {
errorPlacementFunction(error, inputElement);
showOneError();
}
settings.success = function (error) {
successFunction(error);
showOneError();
}
function showOneError() {
var $errors = $(form).find(".field-validation-error");
$errors.slice(1).hide();
$errors.filter(":first:not(:visible)").show();
}
});
</script>
可以试试你的控制器动作
var goodErrors = ModelState.GroupBy(MS => MS.Key).Select(ms => ms.First()).ToDictionary(ms => ms.Key, ms => ms.Value);
ModelState.Clear();
foreach (var item in goodErrors)
{
ModelState.Add(item.Key, item.Value);
}
我只是选择每个属性错误中的一个,清除所有错误然后将单个错误添加回来。
这是完全未经测试的,但应该可以工作。
您可以创建一个仅显示第一个错误的自定义验证摘要。这可以通过为 HtmlHelper 类创建扩展或编写您自己的 HtmlHelper 来完成。前者更直接。
public static class HtmlHelperExtensions
{
static string SingleMessageValidationSummary(this HtmlHelper helper, string validationMessage="")
{
string retVal = "";
if (helper.ViewData.ModelState.IsValid)
return "";
retVal += @"<div class=""notification-warnings""><span>";
if (!String.IsNullOrEmpty(validationMessage))
retVal += validationMessage;
retVal += "</span>";
retVal += @"<div class=""text"">";
foreach (var key in helper.ViewData.ModelState.Keys)
{
foreach(var err in helper.ViewData.ModelState[key].Errors)
retVal += "<p>" + err.ErrorMessage + "</p>";
break;
}
retVal += "</div></div>";
return retVal.ToString();
}
}
这是针对 ValidationSummary 的,但也可以针对ValidationMessageFor
.
请参阅:自定义 ValidationSummary 模板 Asp.net MVC 3
更新 jquery.validate.unobtrusive.js。特别是onError
功能,它说error.removeClass("input-validation-error").appendTo(container);
未经测试,但将该行更改为:error.removeClass("input-validation-error").eq(0).appendTo(container);
创建一个html helper extension
只呈现一条消息的。
public static MvcHtmlString ValidationError(this HtmlHelper helper)
{
var result = new StringBuilder();
var tag = new TagBuilder("div");
tag.AddCssClass("validation-summary-errors");
var firstError = helper.ViewData.ModelState.SelectMany(k => k.Value.Errors).FirstOrDefault();
if (firstError != null)
{
tag.InnerHtml = firstError.ErrorMessage;
}
result.Append(tag.ToString());
return MvcHtmlString.Create(result.ToString());
}
更新jquery.validate.unobtrusive.js
OnErrors
函数如下,
function onErrors(form, validator) { // 'this' is the form element
// newly added condition
if ($(form.currentTarget).hasClass("one-error")) {
var container = $(this).find(".validation-summary-errors");
var firstError = validator.errorList[0];
$(container).html(firstError.message);
}
else {
var container = $(this).find("[data-valmsg-summary=true]"),
list = container.find("ul");
if (list && list.length && validator.errorList.length) {
list.empty();
container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
$.each(validator.errorList, function () {
$("<li />").html(this.message).appendTo(list);
});
}
}
}
基本上我们在表单中添加了一个条件OnError
来检查表单是否包含一个名为的 css 类one-error
,如果是,则显示一个错误,否则显示全部。