使用数据注释强制模型的布尔值为真

29

这里有一个简单的问题(我想是这样)。

我有一个表单,在底部有一个复选框,要求用户同意条款和条件。如果用户没有勾选框,则希望在我的验证摘要中显示错误消息,以及其他表单错误。

我将以下内容添加到我的视图模型中:

[Required]
[Range(1, 1, ErrorMessage = "You must agree to the Terms and Conditions")]
public bool AgreeTerms { get; set; }

但是那个方法不起作用。

是否有一种简单的方式可以通过数据注释来强制一个值为真?


自定义注解非常容易编写,您考虑过这个选项吗? - asawyer
不是针对布尔值,但非常相似(并允许自定义错误消息):http://rical.blogspot.com/2012/03/server-side-custom-annotation.html - pkr
4个回答

28
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace Checked.Entitites
{
    public class BooleanRequiredAttribute : ValidationAttribute, IClientValidatable
    {
        public override bool IsValid(object value)
        {
            return value != null && (bool)value == true;
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            //return new ModelClientValidationRule[] { new ModelClientValidationRule() { ValidationType = "booleanrequired", ErrorMessage = this.ErrorMessage } };
            yield return new ModelClientValidationRule() 
            { 
                ValidationType = "booleanrequired", 
                ErrorMessage = this.ErrorMessageString 
            };
        }
    }
}

10

实际上,使用DataAnnotations有一种可行的方法来实现它。方法如下:

    [Required]
    [Range(typeof(bool), "true", "true")]
    public bool AcceptTerms { get; set; }

这对我没有用,因为客户端验证在 true 和 false 时都触发了。 - Peter
1
很好用,并且可以指定错误信息来覆盖默认的范围消息:[Required, Range(typeof(bool), "true", "true", ErrorMessage = "接受条款是必需的")] - Subjective Reality

7

您可以编写自定义验证属性,这已经提到过了。如果您正在进行客户端验证,则需要编写自定义JavaScript以启用不显眼的验证功能来捕捉它。例如,如果您正在使用jQuery:

// extend jquery unobtrusive validation
(function ($) {

  // add the validator for the boolean attribute
  $.validator.addMethod(
    "booleanrequired",
    function (value, element, params) {

      // value: the value entered into the input
      // element: the element being validated
      // params: the parameters specified in the unobtrusive adapter

      // do your validation here an return true or false

    });

  // you then need to hook the custom validation attribute into the MS unobtrusive validators
  $.validator.unobtrusive.adapters.add(
    "booleanrequired", // adapter name
    ["booleanrequired"], // the names for the properties on the object that will be passed to the validator method
    function(options) {

      // set the properties for the validator method
      options.rules["booleanRequired"] = options.params;

      // set the message to output if validation fails
      options.messages["booleanRequired] = options.message;

    });

} (jQuery));

另一种方法(有点像hack,我不太喜欢)是在您的模型上设置一个始终为true的属性,然后使用CompareAttribute来比较* AgreeTerms *属性的值。这很简单,但我不喜欢它 :)


键区分大小写:booleanrequired booleanRequired - Davi Fiamenghi

3

ASP.Net Core 3.1

我知道这是一个非常老的问题,但对于asp.net核心而言, IClientValidatable不存在。我需要一种解决方案,可以与 jQuery Unobtrusive Validation 以及服务器验证结合使用,因此借鉴了这个 Stack Overflow 的问题链接, 我进行了一些小修改,使其适用于布尔字段,如复选框。

特性代码

   [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
    public class MustBeTrueAttribute : ValidationAttribute, IClientModelValidator
    {
        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            var errorMsg = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-mustbetrue", errorMsg);
        }

        public override bool IsValid(object value)
        {
            return value != null && (bool)value == true;
        }

        private bool MergeAttribute(
                  IDictionary<string, string> attributes,
                  string key,
                  string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }

    }

模型

    [Display(Name = "Privacy policy")]
    [MustBeTrue(ErrorMessage = "Please accept our privacy policy!")]
    public bool PrivacyPolicy { get; set; }

客户端代码

$.validator.addMethod("mustbetrue",
    function (value, element, parameters) {
        return element.checked;
    });

$.validator.unobtrusive.adapters.add("mustbetrue", [], function (options) {
    options.rules.mustbetrue = {};
    options.messages["mustbetrue"] = options.message;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接