Enforcing a model's boolean value to be true u

2019-01-19 10:34发布

问题:

Simple problem here (I think).

I have a form with a checkbox at the bottom where the user must agree to the terms and conditions. If the user doesn't check the box, I'd like an error message to be displayed in my validation summary along with the other form errors.

I added this to my view model:

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

But that didn't work.

Is there an easy way to force a value to be true with data annotations?

回答1:

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 
            };
        }
    }
}


回答2:

You can write a custom validation attribute which has already been mentioned. You will need to write custom javascript to enable the unobtrusive validation functionality to pick it up if you are doing client side validation. e.g. if you are using 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));

Another way (which is a bit of a hack and I don't like it) is to have a property on your model that is always set to true, then use the CompareAttribute to compare the value of your *AgreeTerms * attribute. Simple yes but I don't like it :)