我有一个这样的视图模型:
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; }
}
视图标记代码:
<%= Html.CheckBoxFor(m => m.AgreesWithTerms) %>
<%= Html.LabelFor(m => m.AgreesWithTerms)%>
结果:
未执行验证。到目前为止,这没关系,因为bool是一个值类型,永远不会为null。但即使我使AgreesWithTerms可以为空,它也无法工作,因为编译器会喊叫
“模板只能用于字段访问,属性访问,单维数组索引或单参数自定义索引器表达式。”
那么,处理这个问题的正确方法是什么?
答案 0 :(得分:91)
我的解决方案如下(它与已提交的答案没有太大差别,但我相信它的名字更好):
/// <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;
}
}
然后你可以在你的模型中使用它:
[MustBeTrue(ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }
答案 1 :(得分:48)
我会为服务器端和客户端创建验证器。使用MVC和不显眼的表单验证,只需执行以下操作即可实现:
首先,在项目中创建一个类来执行服务器端验证,如下所示:
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"
};
}
}
在此之后,在模型中注释相应的属性:
[EnforceTrue(ErrorMessage=@"Error Message")]
public bool ThisMustBeTrue{ get; set; }
最后,通过在View中添加以下脚本来启用客户端验证:
<script type="text/javascript">
jQuery.validator.addMethod("enforcetrue", function (value, element, param) {
return element.checked;
});
jQuery.validator.unobtrusive.adapters.addBool("enforcetrue");
</script>
注意:我们已经创建了一个方法GetClientValidationRules
,它将我们的注释从我们的模型推送到视图。
答案 2 :(得分:18)
我是通过创建自定义属性获得的:
public class BooleanRequiredAttribute : RequiredAttribute
{
public override bool IsValid(object value)
{
return value != null && (bool) value;
}
}
答案 3 :(得分:6)
[Compare("Remember", ErrorMessage = "You must accept the terms and conditions")]
public bool Remember { get; set; }
答案 4 :(得分:5)
这可能是“黑客”,但你可以使用内置的Range属性:
[Display(Name = "Accepted Terms Of Service")]
[Range(typeof(bool), "true", "true")]
public bool Terms { get; set; }
唯一的问题是“警告”字符串会说“FIELDNAME必须介于真与真”。
答案 5 :(得分:4)
“必需”是错误的验证,在这里。你想要的东西类似于“必须具有真值”,这与“必需”不同。怎么样使用像:
[RegularExpression("^true")]
答案 6 :(得分:3)
我的解决方案是布尔值的这个简单自定义属性:
public class BooleanAttribute : ValidationAttribute
{
public bool Value
{
get;
set;
}
public override bool IsValid(object value)
{
return value != null && value is bool && (bool)value == Value;
}
}
然后你可以在你的模型中使用它:
[Required]
[Boolean(Value = true, ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }
答案 7 :(得分:3)
我只是充分利用现有的解决方案,并将它们整合到一个允许服务器端和客户端验证的答案中。
/// <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",
};
}
}
jQuery.validator.addMethod("mustbetrue", function (value, element) {
return element.checked;
});
jQuery.validator.unobtrusive.adapters.addBool("mustbetrue");
答案 8 :(得分:2)
对于那些在客户端(以前是我)进行验证时遇到问题的人:确保你也有
这是一个很好的教程,但是错过了第4步。
答案 9 :(得分:2)
执行此操作的正确方法是检查类型!
[Range(typeof(bool), "true", "true", ErrorMessage = "You must or else!")]
public bool AgreesWithTerms { get; set; }
答案 10 :(得分:1)
在此处找到了更完整的解决方案(服务器端和客户端验证):
http://blog.degree.no/2012/03/validation-of-required-checkbox-in-asp-net-mvc/#comments
答案 11 :(得分:1)
添加[RegularExpression]:
就足够了[DisplayName("I accept terms and conditions")]
[RegularExpression("True", ErrorMessage = "You must accept the terms and conditions")]
public bool AgreesWithTerms { get; set; }
注意 - “True”必须以大写字母T
开头