【问题标题】:Required Checkbox validation works in reverse for Html.CheckBoxFor [duplicate]Html.CheckBoxFor 所需的复选框验证反向工作 [重复]
【发布时间】:2018-02-21 14:24:20
【问题描述】:

在提交页面之前,我有一个复选框验证。但它反过来起作用。当我选中该框而不是相反时,它显示错误消息。我不知道我在哪里做错了。

我的视图模型

[Display(Name = "Terms and Conditions")]
[Range(typeof(bool), "true", "true", ErrorMessage = "Please accept Terms & Conditions")]
public bool IsTermsAccepted { get; set; }

我的观点

<div class="row col-lg-offset-2 top-buffer">
                @Html.CheckBoxFor(model => model.IsTermsAccepted)
                @Html.LabelFor(model => model.IsTermsAccepted)
            <br>@Html.ValidationMessageFor(model => model.IsTermsAccepted)
        </div>

感谢您的宝贵时间!

Edit1:我跟here一模一样

Edit2:我可以通过添加一个简单的脚本来解决这个问题(如上面提到的链接所示)

<script>
// extend range validator method to treat checkboxes differently
var defaultRangeValidator = $.validator.methods.range;
$.validator.methods.range = function(value, element, param) {
    if(element.type === 'checkbox') {
        // if it's a checkbox return true if it is checked
        return element.checked;
    } else {
        // otherwise run the default validation function
        return defaultRangeValidator.call(this, value, element, param);
    }
}

【问题讨论】:

    标签: c# html asp.net-mvc razor checkbox


    【解决方案1】:

    您需要了解 CheckBoxFor 在 ASP.NET MVC 中的工作原理 - 以及复选框在 HTML 中的工作原理(请参阅我对这个问题的回答:https://stackoverflow.com/a/11424091/159145

    • 如果未选中,HTML 复选框不会在 POST 请求正文中发布其值。
    • 因此,为了区分“checkbox-not-checked”和“checkbox-excluded”,您需要包含一个明确的“false”值,如&lt;input type="hidden" /&gt;,其name="" 属性值与复选框输入的相同.
    • ASP.NET MVC 为您执行此操作:Html.CheckBoxFor() 同时呈现 &lt;input type="checkbox" value="true" /&gt; &lt;input type="hidden" value="false" /&gt;
      • 如果您查看页面呈现的 HTML,您会同时看到它们。

    因此,当您提交选中的复选框时,您的浏览器实际上会发送 两个 值:truefalse。是 "false" 值导致您的 Range 验证器失败,即使它也发送了 true 值。

    但是,RangeValidatorAttribute 不够聪明,无法处理使用 CheckBoxFor 设置的布尔 ViewModel 属性的这种特定情况。

    据我所知,没有内置的 DataAnnotation 属性可以处理这种情况 - 您需要自己在 Controller Action 中实现它,如下所示:

    [HttpPost]
    public IHttpActionResult Foo(FooViewModel model) {
    
        if( !model.IsTermsAccepted ) {
    
            this.ModelState.AddModelError( nameof(model.IsTermsAccepted), "you must accept the terms." );
            return this.View( model );
        }
    
    }
    

    ...或者您可以尝试自己实现一个新的验证属性,它需要做这样的事情。

    注意它源自Required 属性,因为您需要确保该属性在请求正文中具有值(即复选框包含在响应中,具有隐藏输入)和 em> true 值存在。

    [AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
    class CheckboxIsCheckedAttribute : RequiredAttribute {
    
        public override bool IsValid(Object value) {
    
            Boolean isRequiredValid = base.IsValid( value );
            if( !isRequiredValid ) return false;
    
            return (value as Boolean) == true;
        }
    }
    

    【讨论】:

    • 很好的解释,但请注意,它不应该来自RequiredAttribute - 只是来自ValidationAttribute(因为它是bool,无论如何默认情况下它都是必需的,如果存在验证错误将已经添加在响应中没有价值)。此外,如果您从RequiredAttribute 派生,它还必须在global.asax 中注册(欺骗中的dazbradbury 答案是正确的方法,并且还提供客户端验证)
    猜你喜欢
    • 2018-01-06
    • 2013-04-19
    • 2021-01-17
    • 1970-01-01
    • 2014-03-15
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多