How to add boolean required attribute in mvc?

I have one model class like:

public class Student
{
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "Enrollment Date")]
    public DateTime EnrollmentDate { get; set; }

    [Required]
    [Display(Name = "Is Active")]
    public bool IsActive { get; set; }

    public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Here I have created a Boolean property IsActive with Required attribute, but the problem is that my view is not executing the required validation for this property? I want to bind this property with a CheckBox and check if this CheckBox is checked and run validation if it is not.

Any solution for this?


[Display(Name = "Is Active")]
[Range(typeof(bool), "true", "true", ErrorMessage="The field Is Active must be checked.")]
public bool IsActive { get; set; }

Thanks for the above solution, which put me in right direction, but for me it didn't work well. I need to add below script to the page that extends jquery validator to get the above solution work. Thought of sharing this if at all someone runs into similar issue.

<script>
        // extend jquery range validator to work for required checkboxes
        var defaultRangeValidator = $.validator.methods.range;
        $.validator.methods.range = function(value, element, param) {
            if(element.type === 'checkbox') {
                // if it's a checkbox return true if it is checked
                return element.checked;
            } else {
                // otherwise run the default validation function
                return defaultRangeValidator.call(this, value, element, param);
            }
        }
</script>

Let me add a little to Sonu K post

If you use HTML validation on it(<input type="checkbox" required/>) it might end up disrupting your javascript from preventing you to submit an empty required field set from your Model

Finally, if you don't want the Is Active to be added to database when doing migration(Code first) just add [NotMapped]

Full code

[NotMapped]
[Display(Name = "Is Active")]
[Range(typeof(bool), "true", "true", ErrorMessage="The field Is Active must be checked.")]
public bool IsActive { get; set; }

because it is set as true by default in MVC despite it will display uncheck on the browser, so the validation might not work as you expect it to, that is why you have to add this javascript code to perfect the validation.

<script>
            // extend jquery range validator to work for required checkboxes
            var defaultRangeValidator = $.validator.methods.range;
            $.validator.methods.range = function(value, element, param) {
                if(element.type === 'checkbox') {
                    // if it's a checkbox return true if it is checked
                    return element.checked;
                } else {
                    // otherwise run the default validation function
                    return defaultRangeValidator.call(this, value, element, param);
                }
            }
        </script>

Enjoy coding


This code was given to me recently:

public class BooleanRequiredAttribute : ValidationAttribute, IClientValidatable
    {
        public override bool IsValid(object value)
        {
            return value is bool && (bool)value;
        }



        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            yield return new ModelClientValidationRule
            {
                ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
                ValidationType = "booleanrequired"
            };
        }
    }

You then add the following in place just after you define the validation js:

$.validator.unobtrusive.adapters.addBool("booleanrequired", "required");

Although I like the idea of using Range, it's easy and less code, the above gives you a proper attribute that is meaningful to future developers.