C# 所需的复选框验证与Html相反。CheckBoxFor
在提交页面之前,我有一个复选框验证。但事实恰恰相反。当我选中该框而不是相反时,它会显示错误消息。我不知道我哪里做错了 我的视图模型C# 所需的复选框验证与Html相反。CheckBoxFor,c#,html,asp.net-mvc,razor,checkbox,C#,Html,Asp.net Mvc,Razor,Checkbox,在提交页面之前,我有一个复选框验证。但事实恰恰相反。当我选中该框而不是相反时,它会显示错误消息。我不知道我哪里做错了 我的视图模型 [Display(Name = "Terms and Conditions")] [Range(typeof(bool), "true", "true", ErrorMessage = "Please accept Terms & Conditions")] public bool IsTermsAccepted { get; set; } 我的看法 &l
[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>
@CheckBoxFor(model=>model.IsTermsAccepted)
@LabelFor(model=>model.IsTermsAccepted)
@Html.ValidationMessageFor(model=>model.IsTermsAccepted)
谢谢你抽出时间
伊迪丝1:我跟他一模一样
Edit2:我可以通过添加一个简单的脚本来解决这个问题(如上面提到的链接所示)
//扩展范围验证器方法以区别对待复选框
var defaultRangeValidator=$.validator.methods.range;
$.validator.methods.range=函数(值、元素、参数){
如果(element.type==='checkbox'){
//如果是复选框,则选中后返回true
返回元素。已选中;
}否则{
//否则,运行默认的验证函数
返回defaultRangeValidator.call(this,value,element,param);
}
}
您需要了解
复选框for
在ASP.NET MVC中是如何工作的,以及复选框在HTML中是如何工作的(请参阅我对这个问题的回答:)
- 如果未选中HTML复选框,则不会在
请求正文中发布其值post
- 因此,为了区分“未选中复选框”和“排除复选框”之间的区别,您需要包含一个明确的“false”值,如
,其属性值与复选框输入的属性值相同 - ASP.NET MVC为您做了这件事:
同时呈现Html.CheckBoxFor()
和
- 如果查看页面的呈现HTML,您将同时看到它们
true
和false
。是“false”
值导致范围
验证器失败,即使它也发送了真值
但是,RangeValidatorAttribute
不够智能,无法处理使用CheckBoxFor
设置的布尔ViewModel属性的这种特定情况
据我所知,没有处理这种情况的内置DataAnnotation
属性-您需要在控制器操作中自己实现它,如下所示:
[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
属性,因为您需要确保属性在请求正文中具有值(即复选框包含在响应中,带有隐藏输入),并且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
中注册(dupe中的dazbradbury答案是正确的方法,并提供客户端验证)
[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;
}
}