ASP.NET mVC 3.0 验证 MVCContrib CheckboxList

发布于 2024-11-10 17:29:21 字数 3342 浏览 0 评论 0原文

我实现了一个自定义验证器来检查是否至少检查了某些内容:

public class AtLestOneRequiredAttribute : RequiredAttribute
    {
        public override bool IsValid(object value)
        {
            return (value != null);
        }
    }

    public class RequiredListValidator : DataAnnotationsModelValidator<AtLestOneRequiredAttribute>
    {
        private readonly string errorMessage;

        /// <summary>
        /// Initializes a new instance of the <see cref="EmailValidator"/> class.
        /// </summary>
        /// <param name="metadata">The metadata.</param>
        /// <param name="context">The context.</param>
        /// <param name="attribute">The attribute.</param>
        public RequiredListValidator(ModelMetadata metadata, ControllerContext context, AtLestOneRequiredAttribute attribute)
            : base(metadata, context, attribute)
        {
            this.errorMessage = attribute.ErrorMessage;
        }

        /// <summary>
        /// Retrieves a collection of client validation rules.
        /// </summary>
        /// <returns>A collection of client validation rules.</returns>
        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = errorMessage,
                ValidationType = "atlestonerequired"
            };

            return new[] { rule };
        }        
    }

我还为该选择生成了不显眼的验证属性(http://weblogs.asp.net/srkirkland/archive/2011/03/08/adding-unobtrusive-validation-to- mvccontrib- Fluent-html.aspx)

模型:

[AtLestOneRequired(ErrorMessage="At least one selection required")]
        public IList<int> MyCheckBox{ get; set; }

视图:

@this.CheckBoxList(x => x.MyCheckBox).Options(Model.MyCheckBoxes).IncludeUnobtrusiveValidationAttributes(Html)

结果我得到了这个具有不显眼属性的 html:

<div data-val="true" data-val-atlestonerequired="At least one selection required" id="MyCheckBox">
    <input id="MyCheckBox_0" name="MyCheckBox" type="checkbox" value="1"/>
    <label for="MyCheckBox_0" id="MyCheckBox_0_Label">A</label>
    <input id="MyCheckBox_1" name="MyCheckBox" type="checkbox" value="2"/>
    <label for="MyCheckBox_1" id="MyCheckBox_1_Label">B</label>
    <input id="MyCheckBox_2" name="MyCheckBox" type="checkbox" value="3"/>
    <label for="MyCheckBox_2" id="MyCheckBox_2_Label">C</label>
    <input id="MyCheckBox_3" name="MyCheckBox" type="checkbox" value="4"/>
    <label for="MyCheckBox_3" id="MyCheckBox_3_Label">D</label>
    ....
</div>

但我的验证在客户端上不起作用侧面,我需要做些什么才能使其发挥作用?我想在这种情况下我可能需要实现自定义 jQuery 验证方法,如果默认情况下它不起作用?

尝试添加此:

jQuery.validator.addMethod("atlestonerequired", function (value, element) {
             return (value != null);
         });

         jQuery.validator.unobtrusive.adapters.addBool('atlestonerequired');

不起作用。

I implement a custom validator to check if there is at least something checked:

public class AtLestOneRequiredAttribute : RequiredAttribute
    {
        public override bool IsValid(object value)
        {
            return (value != null);
        }
    }

    public class RequiredListValidator : DataAnnotationsModelValidator<AtLestOneRequiredAttribute>
    {
        private readonly string errorMessage;

        /// <summary>
        /// Initializes a new instance of the <see cref="EmailValidator"/> class.
        /// </summary>
        /// <param name="metadata">The metadata.</param>
        /// <param name="context">The context.</param>
        /// <param name="attribute">The attribute.</param>
        public RequiredListValidator(ModelMetadata metadata, ControllerContext context, AtLestOneRequiredAttribute attribute)
            : base(metadata, context, attribute)
        {
            this.errorMessage = attribute.ErrorMessage;
        }

        /// <summary>
        /// Retrieves a collection of client validation rules.
        /// </summary>
        /// <returns>A collection of client validation rules.</returns>
        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = errorMessage,
                ValidationType = "atlestonerequired"
            };

            return new[] { rule };
        }        
    }

I also generate Unobtrusive Validation Attributes for that select (http://weblogs.asp.net/srkirkland/archive/2011/03/08/adding-unobtrusive-validation-to-mvccontrib-fluent-html.aspx)

Model:

[AtLestOneRequired(ErrorMessage="At least one selection required")]
        public IList<int> MyCheckBox{ get; set; }

View:

@this.CheckBoxList(x => x.MyCheckBox).Options(Model.MyCheckBoxes).IncludeUnobtrusiveValidationAttributes(Html)

In result i am getting this html with unobtrusive attributes in:

<div data-val="true" data-val-atlestonerequired="At least one selection required" id="MyCheckBox">
    <input id="MyCheckBox_0" name="MyCheckBox" type="checkbox" value="1"/>
    <label for="MyCheckBox_0" id="MyCheckBox_0_Label">A</label>
    <input id="MyCheckBox_1" name="MyCheckBox" type="checkbox" value="2"/>
    <label for="MyCheckBox_1" id="MyCheckBox_1_Label">B</label>
    <input id="MyCheckBox_2" name="MyCheckBox" type="checkbox" value="3"/>
    <label for="MyCheckBox_2" id="MyCheckBox_2_Label">C</label>
    <input id="MyCheckBox_3" name="MyCheckBox" type="checkbox" value="4"/>
    <label for="MyCheckBox_3" id="MyCheckBox_3_Label">D</label>
    ....
</div>

But my validaton does not work on client side, anything i need to do to make it work? I think may be i need to implement custom jQuery validaton method in that case if by default it is not working?

tried to add this:

jQuery.validator.addMethod("atlestonerequired", function (value, element) {
             return (value != null);
         });

         jQuery.validator.unobtrusive.adapters.addBool('atlestonerequired');

does not work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

櫻之舞 2024-11-17 17:29:21

在这个问题上花了一些时间。
客户端验证不起作用的原因是非侵入式验证选择需要验证的项目的方式。特别是以下行:

$(selector).find(":input[data-val=true]").each(function () {
  $jQval.unobtrusive.parseElement(this, true);
});

如果您注意到仅适用于 input|select|textarea|button":input"

这意味着您的 "div[data- val=true]" 将不会被选择。

解决这个问题的方法是类似于单选按钮的“必需”。

<div name="CheckBox" id="CheckBox">
  <input type="checkbox" data-val-cbrequired="Required" data-val="true" value="Default" name="CheckBox_0" id="CheckBox_0">
  <label for="CheckBox_0">Checkbox</label>
  <input type="checkbox" value="Yes" name="CheckBox_1" id="CheckBox_1">
  <label for="CheckBox_1">Yes</label>
  <input type="checkbox" value="No" name="CheckBox_2" id="CheckBox_2">
  <label for="CheckBox_2">No</label>
</div>

然后对于 Jquery 验证添加:

$.validator.unobtrusive.adapters.addBool("cbrequired", "required");

Spent some time on this issue.
The reason that the client validation is not working is the way the unobtrusive validation selects the items that need to be validated. In particular the following line:

$(selector).find(":input[data-val=true]").each(function () {
  $jQval.unobtrusive.parseElement(this, true);
});

if you notice the ":input" which only applies to input|select|textarea|button

This means your "div[data-val=true]" will not be selected.

The way to get around this is to do this similar to the Required for a Radio button.

<div name="CheckBox" id="CheckBox">
  <input type="checkbox" data-val-cbrequired="Required" data-val="true" value="Default" name="CheckBox_0" id="CheckBox_0">
  <label for="CheckBox_0">Checkbox</label>
  <input type="checkbox" value="Yes" name="CheckBox_1" id="CheckBox_1">
  <label for="CheckBox_1">Yes</label>
  <input type="checkbox" value="No" name="CheckBox_2" id="CheckBox_2">
  <label for="CheckBox_2">No</label>
</div>

Then for the Jquery validation add:

$.validator.unobtrusive.adapters.addBool("cbrequired", "required");
送你一个梦 2024-11-17 17:29:21

我不知道这个问题的公认解决方案。但这里有一个解决方法。

我的复选框为:

<input name="TermsNConditions" type="checkbox" id="TermsNConditions" tabindex="12" />

模型具有此属性:

    [Required(ErrorMessage = "(Please accept the terms and conditions)")]
    [DefaultValue(0)]
    [RegularExpression(@"[^0]", ErrorMessage = "(Please accept the terms and conditions)")]
    public int AcceptTermsNConditions { get; set; }

及其隐藏字段

<%:Html.HiddenFor(model=>model.AcceptTermsNConditions) %>

我在复选框上调用 javascript 更改事件,如下所示:

$(function () {
        $("#TermsNConditions").live("change", function () {
            if ($("#TermsNConditions").attr('checked')) {
                $("#AcceptTermsNConditions").val(1);
            }
            else {
                $("#AcceptTermsNConditions").val(0);
            }
        });
        if ($("#AcceptTermsNConditions").val() == 1) {
            $("#TermsNConditions").attr('checked', true);
        }
    });

上面的脚本设置隐藏字段的值,并针对该隐藏字段验证模型场地。

I dont know the accepted solution for this problem. But here is a work around for it.

I have the check box as:

<input name="TermsNConditions" type="checkbox" id="TermsNConditions" tabindex="12" />

The model has this property:

    [Required(ErrorMessage = "(Please accept the terms and conditions)")]
    [DefaultValue(0)]
    [RegularExpression(@"[^0]", ErrorMessage = "(Please accept the terms and conditions)")]
    public int AcceptTermsNConditions { get; set; }

and a hidden field for it

<%:Html.HiddenFor(model=>model.AcceptTermsNConditions) %>

I call a javascript change event on the check box as below:

$(function () {
        $("#TermsNConditions").live("change", function () {
            if ($("#TermsNConditions").attr('checked')) {
                $("#AcceptTermsNConditions").val(1);
            }
            else {
                $("#AcceptTermsNConditions").val(0);
            }
        });
        if ($("#AcceptTermsNConditions").val() == 1) {
            $("#TermsNConditions").attr('checked', true);
        }
    });

The above script sets the value for the hidden field and the model is validated against that hidden field.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文