49

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?

Sonu K
  • 2,562
  • 2
  • 20
  • 32
  • 2
    Don't think you can do it with Required. Have a look here. This might help http://www.jasonwatmore.com/post/2013/10/16/ASPNET-MVC-Required-Checkbox-with-Data-Annotations.aspx – mjroodt Sep 30 '14 at 13:38
  • 3
    The `Required` attribute just means that the property has to have a value. In the case of boolean (checkbox) the value false (or unchecked) is still a valid answer. – DavidG Sep 30 '14 at 13:38
  • I knew this fact that it is not working because unchecked is also a valid value for Boolean property, that's why I am looking for a solution to this. I want to know if it is possible using default Data Annotations in MVC? – Sonu K Sep 30 '14 at 13:40
  • @SonuK you can do it using the custom validation attribute. Read the link I added – mjroodt Sep 30 '14 at 13:50

5 Answers5

98
[Display(Name = "Is Active")]
[Range(typeof(bool), "true", "true", ErrorMessage="The field Is Active must be checked.")]
public bool IsActive { get; set; }
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Sonu K
  • 2,562
  • 2
  • 20
  • 32
31

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>
Kris
  • 545
  • 7
  • 9
13

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

Odin
  • 921
  • 8
  • 12
3

If you set IsActive as nullable then it should show the error message.

[Required(ErrorMessage = "Is Active")]
public bool? IsActive { get; set; }
Andreea
  • 49
  • 1
  • Bingo! Easy, and follows .NET Documentation too: [Model Validation in ASP.NET Web API](https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api) *"To force clients to set a value, make the property nullable and set the Required attribute:"* – Michael R Aug 16 '22 at 22:28
  • Will this give a validation error if the boolean is false? – Enrico Mar 22 '23 at 16:08
1

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.

Colin Wiseman
  • 848
  • 6
  • 10