用于CheckBox的MVC 3 Custom ValidationAttribute在客户端上触发两次

我将阐述代码来解释整个情况,然后提出问题的描述:

在我的视图模型中,我有一个布尔属性来跟踪用户是否接受了术语:

 [MustBeTrue(ErrorMessageResourceType = typeof(ErrorMessages), ErrorMessageResourceName = "MustAccept")]
 public bool HasAuthorizedBanking { get; set; }

正如你所看到的,我已经创建了一个自定义验证属性来处理这个名为MustBeTrue来处理复选框,因为[Required]当前不适用于MVC 3中复选框的客户端验证

public class MustBeTrueAttribute : ValidationAttribute, IClientValidatable
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if ((bool)value)
            return ValidationResult.Success;

        return new ValidationResult(String.Format(ErrorMessageString,validationContext.DisplayName));
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "truerequired"
        };

        yield return rule;
    }
}

然后我添加一个带有ValidationMessage的CheckBoxFor到我的视图中:

@Html.CheckBoxFor(model => model.HasAuthorizedBanking)
@Html.ValidationMessageFor(model => model.HasAuthorizedBanking, "", new { @class = "validationtext" })  

为了实现这个客户端,我创建了一个jQuery验证器方法,并添加了一个不显眼的适配器:

// Checkbox Validation
jQuery.validator.addMethod("checkrequired", function (value, element) {
    var checked = false;
    checked = $(element).is(':checked');
    return checked;
}, '');

jQuery.validator.unobtrusive.adapters.addBool("truerequired", "checkrequired");

在我看来,注册过程中的所有步骤都在一个页面上,元素隐藏并通过jQuery显示,并使用jQuery验证进行验证。 当点击“下一步”按钮时,会触发页面上的每个输入元素进行验证:

 var validator = $("#WizardForm").validate(); // obtain validator
    var anyError = false;
    $step.find("input").each(function () {
        if (!validator.element(this)) { // validate every input element inside this step
            anyError = true;
        }

    });

    if (anyError)
        return false;

笔记:

  • 我的模型中只有一个属性具有MustBeTrue属性,并且在整个页面上只有一个CheckBoxFor&matching ValidationMessageFor。
  • 为了跟踪何时调用这个方法,我只需要提醒一下(检查); 在jQuery Validator方法'checkrequired'中。
  • 问题:当复选框被选中/取消选中时,'checkrequired'方法被触发一次。 但是,当单击“下一步”按钮并且我们启动验证所有输入元素时,无论是否选中复选框,都会触发两次。 有趣的是,如果它被选中,第一个验证返回true,第二个返回false(这第二个错误返回是我的主要问题 - 页面不会验证,并且不允许你继续下一步)。 此外,当它被选中并点击下一个时 - ValidationMessageFor消息就会消失,就像它是有效的一样。

    编辑:我有另一个自定义属性用于在jQuery DatePicker文本框中验证Age,虽然它以完全相同的方式实现 - 它只在相同条件下触发一次。


    事实证明,问题是Html.CheckBoxFor正在生成与复选框同名的第二个输入元素,如下所述:http://forums.asp.net/t/1314753.aspx

    <input data-val="true" data-val-required="The HasAuthorizedBanking field is required." data-val-truerequired="You must accept to continue." id="bankingtermscheckbox" name="HasAuthorizedBanking" type="checkbox" value="true" />
    <input name="HasAuthorizedBanking" type="hidden" value="false" />
    

    解决方法是将jQuery选择器更改为仅查看其类型未隐藏的输入元素:

    $step.find(':input:not(:hidden)').each(function () { // Select all input elements except those that are hidden
            if (!validator.element(this)) { // validate every input element inside this step
                anyError = true;
            }
    
        });
    
        if (anyError)
            return false; // exit if any error found
    
    链接地址: http://www.djcxy.com/p/50927.html

    上一篇: MVC 3 Custom ValidationAttribute for CheckBoxFor firing twice on client

    下一篇: SFTP to EC2 Windows Instance