Search code examples
c#asp.net-mvc-3validationunobtrusive-validation

Either Or Required Validation


I want to use ComponentModel DataAnnotations validate that at least one of two properties has a value. My model looks like this:

public class FooModel {
   public string Bar1 { get; set; }
   public int Bar2 { get; set; }
}

Basically, I want to validate FooModel so that either Bar1 or Bar2 is required. In other words, you can enter one, or the other, or both, but you can't just leave them both empty.

I would prefer that this worked both for server-side and unobtrusive client-side validation.


EDIT: This may be a possible duplicate, as this looks similar to what I'm looking to do


Solution

  • You would need to extend the ValidationAttribute class and over ride the IsValid method, and implement the IClientValidatable if you want to pump custom JavaScript to do the validation. something like below.

    [AttributeUsage(AttributeTargets.Property)]
        public sealed class AtLeastOneOrTwoParamsHasValue : ValidationAttribute, IClientValidatable
        {
            protected override ValidationResult IsValid(object value, ValidationContext validationContext)
            {
                var param1 = validationContext.ObjectInstance.GetType().GetProperty("Param1").GetValue(value, null);
                //var param2 = validationContext.ObjectInstance.GetType().GetProperty("Param2").GetValue(value, null);
    
                //DO Compare logic here.
    
                if (!string.IsNullOrEmpty(Convert.ToString(param1)))
                {
                    return ValidationResult.Success;
                }
    
    
                return new ValidationResult("Some Error");
            }
    
            public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
            {
                //Do custom client side validation hook up
    
                yield return new ModelClientValidationRule
                {
                    ErrorMessage = FormatErrorMessage(metadata.DisplayName),
                    ValidationType = "validParam"
                };
            }
        }
    

    Usage:

    [AtLeastOneOrTwoParamsHasValue(ErrorMessage="Atleast one param must be specified.")]