Search code examples
razorasp.net-coreunobtrusive-validation

Custom Error Message while implementing IValidatableObject


I have implemented IValidatableObject with no issues:

 public class DisclaimerCBs : IValidatableObject
 {
        public bool cb1 { get; set; } = false;
        public bool cb2 { get; set; } = false;
        public bool cb3 { get; set; } = false;

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            Type type = validationContext.ObjectInstance.GetType();
            IEnumerable<PropertyInfo> checkBoxeProperties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.PropertyType == typeof(bool));

            bool allIsChecked = true;
            foreach (PropertyInfo checkBoxProperty in checkBoxeProperties)
            {
                var isChecked = (bool)checkBoxProperty.GetValue(validationContext.ObjectInstance);
                if (!isChecked)
                {
                    allIsChecked = false;
                    break;
                }
            }

            if(!allIsChecked)
                yield return new ValidationResult("Please agree to all Disclaimers. ");

            //TRUE IF THIS FAR
            yield return ValidationResult.Success;
        }
}

However, this only presents the error message in the Validation Summary. I would like to also have this error bring focus to a specified <div> element AND reiterate the error in a label much like property validators do using <span asp-validation-for="Model.Property"></span> . How could I accomplish this?


Solution

  • Replace your Validate method with the following:

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
         Type type = validationContext.ObjectInstance.GetType();
         IEnumerable<PropertyInfo> checkBoxeProperties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.PropertyType == typeof(bool));
    
         List<ValidationResult> validationResult = new List<ValidationResult>();
    
         foreach (PropertyInfo checkBoxProperty in checkBoxeProperties)
         {
             var isChecked = (bool)checkBoxProperty.GetValue(validationContext.ObjectInstance);
             if (!isChecked)
             {
                 validationResult.Add(new ValidationResult("Please agree to this Disclaimer.", new[] { checkBoxProperty.Name }));
             }
         }
    
         return validationResult;
    }