我创建了一个自定义组验证程序,确保用户已填写给定组中的至少一个字段。这在我加载页面并提交表单而不输入任何内容时有效。
但是,问题是表单除了组验证错误之外还有任何错误。当我强制表单显示组所需的验证错误然后显示,例如,组中的一个字段上的字符串长度错误时,组验证错误不会消失。
经过一些调试之后,我非常肯定它的客户端验证无法正常工作,因为每当生成客户端验证时它都不会删除服务器端验证错误。当表单生成字符串长度错误时,它会阻止将表单发布到服务器,这将删除组验证所需的错误。
任何人都可以看到客户端验证码的问题吗?我从此stackoverflow页面MVC3 unobtrusive validation group of inputs复制了代码并更改了它以满足我的需求。这是我第一次尝试自定义验证,如果问题非常简单,请原谅我。另一个指标是,每当我输入然后删除单个字符时,组验证错误都不会打开/关闭。
我在下面提供了自定义验证码:
public class RequireAtLeastOneIfAttribute : ValidationAttribute, IClientValidatable
{
private string[] Properties { get; set; }
public RequireAtLeastOneIfAttribute(params string[] properties)
{
Properties = properties;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if(Properties == null || Properties.Length < 1)
{
return null;
}
foreach (var property in Properties)
{
var propertyInfo = validationContext.ObjectType.GetProperty(property);
var propertyValue = propertyInfo.GetValue(validationContext.ObjectInstance, null);
if (propertyInfo == null)
{
return new ValidationResult(string.Format("Unknown property {0}", property));
}
if (propertyValue is string & !string.IsNullOrEmpty(propertyValue as string))
{
return null;
}
if (propertyValue != null)
{
return null;
}
}
return new ValidationResult("At least one age group field is required");
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = ErrorMessage,
ValidationType = "requireatleaseoneif"
};
rule.ValidationParameters["properties"] = string.Join(",", Properties);
yield return rule;
}
}
我对javascript所做的唯一更改是id。
jQuery.validator.unobtrusive.adapters.add(
'requireatleaseoneif', ['properties'], function (options) {
options.rules['requireatleaseoneif'] = options.params;
options.messages['requireatleaseoneif'] = options.message;
}
);
jQuery.validator.addMethod('requireatleaseoneif', function (value, element, params) {
var properties = params.properties.split(',');
var values = $.map(properties, function (property, index) {
var val = $('#' + property).val();
return val != '' ? val : null;
});
return values.length > 0;
}, '');
@Html.RadioButtonFor(m => m.HaveDependants, true, new { id = "borrower-haveDependants-true", @class = "block-radio-input" })
@Html.RadioButtonFor(m => m.HaveDependants, false, new { id = "borrower-haveDependants-false", @class = "block-radio-input" })
@Html.ValidationMessageFor(m => m.HaveDependants)
@Html.LabelFor(m => m.DependantsAgeGroupOne)
@Html.TextBoxFor(m => m.DependantsAgeGroupOne, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.DependantsAgeGroupOne)
@Html.LabelFor(m => m.DependantsAgeGroupTwo)
@Html.TextBoxFor(m => m.DependantsAgeGroupTwo, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.DependantsAgeGroupTwo)
@Html.LabelFor(m => m.DependantsAgeGroupThree)
@Html.TextBoxFor(m => m.DependantsAgeGroupThree, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.DependantsAgeGroupThree)
我也认为这个问题可能与它的触发方式有关。因为验证属性不在文本输入本身上,而是在单选按钮上,我在按钮单击时添加了以下javascript以验证整个表单。
<script>
$(document).ready(function () {
$(form).validate;
});
</script>
$('input').blur(function () {
$('.haveDependants').valid();
})
答案 0 :(得分:-1)
我的自定义验证属性遇到了同样的问题。默认属性阻止将表单发布到服务器,并且忽略了我的自定义属性。所以这就是我所做的。
禁用客户端表单验证:
@{ Html.EnableClientValidation(false); }
在名为:
if (!ModelState.IsValid)
{
return View(model);
}