ASP.NET MVC自定义验证器客户端验证未触发

时间:2015-12-10 22:38:28

标签: asp.net-mvc validation unobtrusive-validation asp.net-mvc-validation

我创建了一个自定义组验证程序,确保用户已填写给定组中的至少一个字段。这在我加载页面并提交表单而不输入任何内容时有效。

表单无效

enter image description here

有效表格

enter image description here

但是,问题是表单除了组验证错误之外还有任何错误。当我强制表单显示组所需的验证错误然后显示,例如,组中的一个字段上的字符串长度错误时,组验证错误不会消失。

enter image description here

经过一些调试之后,我非常肯定它的客户端验证无法正常工作,因为每当生成客户端验证时它都不会删除服务器端验证错误。当表单生成字符串长度错误时,它会阻止将表单发布到服务器,这将删除组验证所需的错误。

任何人都可以看到客户端验证码的问题吗?我从此stackoverflow页面MVC3 unobtrusive validation group of inputs复制了代码并更改了它以满足我的需求。这是我第一次尝试自定义验证,如果问题非常简单,请原谅我。另一个指标是,每当我输入然后删除单个字符时,组验证错误都不会打开/关闭。

我在下面提供了自定义验证码:

自定义验证器C#(Serverside和Clientside)

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

我对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;
}, '');

Razor

@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>

我将Javascript的最后一位更改为以下

$('input').blur(function () {
   $('.haveDependants').valid();
})

1 个答案:

答案 0 :(得分:-1)

我的自定义验证属性遇到了同样的问题。默认属性阻止将表单发布到服务器,并且忽略了我的自定义属性。所以这就是我所做的。

  1. 禁用客户端表单验证:

    @{ Html.EnableClientValidation(false); }

  2. 在名为:

  3. 的控制器中

    if (!ModelState.IsValid) { return View(model); }