asp.net-mvc 如何使用 DataAnnotations 处理 ASP.NET MVC 2 中的布尔值/复选框?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2245185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to handle Booleans/CheckBoxes in ASP.NET MVC 2 with DataAnnotations?
提问by asp_net
I've got a view model like this:
我有一个这样的视图模型:
public class SignUpViewModel
{
[Required(ErrorMessage = "Bitte lesen und akzeptieren Sie die AGB.")]
[DisplayName("Ich habe die AGB gelesen und akzeptiere diese.")]
public bool AgreesWithTerms { get; set; }
}
The view markup code:
视图标记代码:
<%= Html.CheckBoxFor(m => m.AgreesWithTerms) %>
<%= Html.LabelFor(m => m.AgreesWithTerms)%>
The result:
结果:
No validation is executed. That's okay so far because bool is a value type and never null. But even if I make AgreesWithTerms nullable it won't work because the compiler shouts
不执行验证。到目前为止还可以,因为 bool 是一种值类型并且从不为 null。但即使我将 AgreesWithTerms 设为可空,它也不会起作用,因为编译器会大喊
"Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions."
“模板只能用于字段访问、属性访问、单维数组索引或单参数自定义索引器表达式。”
So, what's the correct way to handle this?
那么,处理这个问题的正确方法是什么?
采纳答案by asp_net
I got it by creating a custom attribute:
我通过创建自定义属性得到了它:
public class BooleanRequiredAttribute : RequiredAttribute
{
public override bool IsValid(object value)
{
return value != null && (bool) value;
}
}
回答by s1mm0t
My Solution is as follows (it's not much different to the answers already submitted, but I believe it's named better):
我的解决方案如下(它与已经提交的答案没有太大区别,但我相信它的命名更好):
/// <summary>
/// Validation attribute that demands that a boolean value must be true.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
return value != null && value is bool && (bool)value;
}
}
Then you can use it like this in your model:
然后你可以在你的模型中像这样使用它:
[MustBeTrue(ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }
回答by dazbradbury
I would create a validator for both Server AND Client side. Using MVC and unobtrusive form validation, this can be achieved simply by doing the following:
我将为服务器和客户端创建一个验证器。使用 MVC 和不显眼的表单验证,只需执行以下操作即可实现:
Firstly, create a class in your project to perform the server side validation like so:
首先,在您的项目中创建一个类来执行服务器端验证,如下所示:
public class EnforceTrueAttribute : ValidationAttribute, IClientValidatable
{
public override bool IsValid(object value)
{
if (value == null) return false;
if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties.");
return (bool)value == true;
}
public override string FormatErrorMessage(string name)
{
return "The " + name + " field must be checked in order to continue.";
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = String.IsNullOrEmpty(ErrorMessage) ? FormatErrorMessage(metadata.DisplayName) : ErrorMessage,
ValidationType = "enforcetrue"
};
}
}
Following this, annotate the appropriate property in your model:
在此之后,在您的模型中注释适当的属性:
[EnforceTrue(ErrorMessage=@"Error Message")]
public bool ThisMustBeTrue{ get; set; }
And Finally, enable client side validation by adding the following script to your View:
最后,通过将以下脚本添加到您的视图来启用客户端验证:
<script type="text/javascript">
jQuery.validator.addMethod("enforcetrue", function (value, element, param) {
return element.checked;
});
jQuery.validator.unobtrusive.adapters.addBool("enforcetrue");
</script>
Note: We already created a method GetClientValidationRuleswhich pushes our annotation to the view from our model.
注意:我们已经创建了一个方法GetClientValidationRules,将我们的注释从我们的模型推送到视图。
回答by ProVega
This might be a "hack" but you can use the built in Range attribute:
这可能是一个“黑客”,但您可以使用内置的 Range 属性:
[Display(Name = "Accepted Terms Of Service")]
[Range(typeof(bool), "true", "true")]
public bool Terms { get; set; }
The only problem is the "warning" string will say "The FIELDNAME must be between True and true".
唯一的问题是“警告”字符串会说“FIELDNAME 必须介于 True 和 true 之间”。
回答by Vedat Taylan
[Compare("Remember", ErrorMessage = "You must accept the terms and conditions")]
public bool Remember { get; set; }
回答by Craig Stuntz
"Required" is the wrong validation, here. You want something akin to "Must have the value true," which is not the same as "Required". What about using something like:
“必需”是错误的验证,在这里。您想要类似于“必须具有真值”的内容,这与“必需”不同。使用类似的东西怎么样:
[RegularExpression("^true")]
?
?
回答by Maksymilian Majer
My solution is this simple custom attribute for boolean values:
我的解决方案是布尔值的这个简单的自定义属性:
public class BooleanAttribute : ValidationAttribute
{
public bool Value
{
get;
set;
}
public override bool IsValid(object value)
{
return value != null && value is bool && (bool)value == Value;
}
}
Then you can use it like this in your model:
然后你可以在你的模型中像这样使用它:
[Required]
[Boolean(Value = true, ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }
回答by James Skimming
I'm just taking the best of the existing solutions and putting it together into a single answer that allows for both server side and client side validation.
我只是将现有解决方案中的最佳解决方案整合到一个允许服务器端和客户端验证的单一答案中。
The to apply to model a properties to ensure a bool value must be true:
用于对属性建模以确保 bool 值必须为真的 :
/// <summary>
/// Validation attribute that demands that a <see cref="bool"/> value must be true.
/// </summary>
/// <remarks>Thank you <c>http://stackoverflow.com/a/22511718</c></remarks>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute, IClientValidatable
{
/// <summary>
/// Initializes a new instance of the <see cref="MustBeTrueAttribute" /> class.
/// </summary>
public MustBeTrueAttribute()
: base(() => "The field {0} must be checked.")
{
}
/// <summary>
/// Checks to see if the given object in <paramref name="value"/> is <c>true</c>.
/// </summary>
/// <param name="value">The value to check.</param>
/// <returns><c>true</c> if the object is a <see cref="bool"/> and <c>true</c>; otherwise <c>false</c>.</returns>
public override bool IsValid(object value)
{
return (value as bool?).GetValueOrDefault();
}
/// <summary>
/// Returns client validation rules for <see cref="bool"/> values that must be true.
/// </summary>
/// <param name="metadata">The model metadata.</param>
/// <param name="context">The controller context.</param>
/// <returns>The client validation rules for this validator.</returns>
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
if (metadata == null)
throw new ArgumentNullException("metadata");
if (context == null)
throw new ArgumentNullException("context");
yield return new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.DisplayName),
ValidationType = "mustbetrue",
};
}
}
The JavaScript to include to make use of unobtrusive validation.
要包含的 JavaScript 以使用不显眼的验证。
jQuery.validator.addMethod("mustbetrue", function (value, element) {
return element.checked;
});
jQuery.validator.unobtrusive.adapters.addBool("mustbetrue");
回答by saj
The proper way to do this is to check the type!
正确的方法是检查类型!
[Range(typeof(bool), "true", "true", ErrorMessage = "You must or else!")]
public bool AgreesWithTerms { get; set; }
回答by Craig Lebowitz
For people who are having trouble getting this working for validation on the client side (formerly me): make sure you have also
对于在客户端(以前是我)进行验证时遇到问题的人:请确保您也有
- Included <% Html.EnableClientValidation(); %> before the form in the view
- Used <%= Html.ValidationMessage or Html.ValidationMessageFor for the field
- Created a DataAnnotationsModelValidator which returns a rule with a custom validation type
- Registered the class deriving from DataAnnotationsModelValidator in the Global.Application_Start
- 包含 <% Html.EnableClientValidation(); %> 在视图中的表单之前
- 用于字段的 <%= Html.ValidationMessage 或 Html.ValidationMessageFor
- 创建了一个 DataAnnotationsModelValidator,它返回一个带有自定义验证类型的规则
- 在 Global.Application_Start 中注册派生自 DataAnnotationsModelValidator 的类
is a good tutorial on doing this, but misses step 4.
是一个很好的教程,但错过了第 4 步。

