c# – MVC 3 CheckBox的自定义ValidationAttribute在客户端触发两次

前端之家收集整理的这篇文章主要介绍了c# – MVC 3 CheckBox的自定义ValidationAttribute在客户端触发两次前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我将列出代码来解释整个情况然后提出问题的描述:

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

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

正如您所看到的,我已经创建了一个自定义验证属性来处理这个名为MustBeTrue的处理CheckBox,因为[required]是currently not working for client-side validation on Checkboxes in MVC 3

  1. public class MustBeTrueAttribute : ValidationAttribute,IClientValidatable
  2. {
  3. protected override ValidationResult IsValid(object value,ValidationContext validationContext)
  4. {
  5. if ((bool)value)
  6. return ValidationResult.Success;
  7.  
  8. return new ValidationResult(String.Format(ErrorMessageString,validationContext.DisplayName));
  9. }
  10.  
  11. public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata Metadata,ControllerContext context)
  12. {
  13. var rule = new ModelClientValidationRule
  14. {
  15. ErrorMessage = FormatErrorMessage(Metadata.GetDisplayName()),ValidationType = "truerequired"
  16. };
  17.  
  18. yield return rule;
  19. }
  20. }

然后我在我的View中添加一个带有ValidationMessage的CheckBoxFor:

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

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

  1. // CheckBox Validation
  2. jQuery.validator.addMethod("checkrequired",function (value,element) {
  3. var checked = false;
  4. checked = $(element).is(':checked');
  5. return checked;
  6. },'');
  7.  
  8. jQuery.validator.unobtrusive.adapters.addBool("truerequired","checkrequired");

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

  1. var validator = $("#WizardForm").validate(); // obtain validator
  2. var anyError = false;
  3. $step.find("input").each(function () {
  4. if (!validator.element(this)) { // validate every input element inside this step
  5. anyError = true;
  6. }
  7.  
  8. });
  9.  
  10. if (anyError)
  11. return false;

笔记:

>我的模型中只有一个属性具有MustBeTrue属性,并且只有一个CheckBoxFor&在整个页面上匹配ValidationMessageFor.
>为了跟踪何时调用方法,我只需发出警报(已选中);在jQuery Validator方法’checkrequired’中.

问题:当选中/取消选中复选框时,会触发’checkrequired方法一次.但是,当单击“下一步”按钮并且我们启动以验证所有输入元素时,无论是否选中该复选框,都会触发两次.有趣的是,如果选中它,第一个验证返回true,第二个验证返回false(第二个错误返回是我的主要问题 – 页面将不会验证,它将不允许您继续下一步).此外,当选中它并单击Next时 – ValidationMessageFor消息将消失,就好像它是有效的一样.

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

解决方法

事实证明,问题是Html.CheckBoxFor正在生成与复选框同名的第二个输入元素,如下所述: http://forums.asp.net/t/1314753.aspx
  1. <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" />
  2. <input name="HasAuthorizedBanking" type="hidden" value="false" />

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

  1. $step.find(':input:not(:hidden)').each(function () { // Select all input elements except those that are hidden
  2. if (!validator.element(this)) { // validate every input element inside this step
  3. anyError = true;
  4. }
  5.  
  6. });
  7.  
  8. if (anyError)
  9. return false; // exit if any error found

猜你在找的C#相关文章