Either Or Required Validation
Asked Answered
E

2

8

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

Esmeralda answered 5/3, 2012 at 0:25 Comment(4)
That's right custom validator is your friend here.Larsen
There is a custom validator called RequiredIf that would solve your problem.Hayne
@JoeTuskan, you're right, I found this blog post on your guidance and it solves my issue. If you'd like to type up an answer so I could give you credit, that's fine by me. If not, have my +1.Esmeralda
AFAIK that should be solved by using different view models, inheriting common properties from a common parent. https://mcmap.net/q/157781/-disable-required-validation-attribute-under-certain-circumstances https://mcmap.net/q/1328284/-disable-validation-on-certain-fieldsUndying
G
7

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.")]
Geodesic answered 5/3, 2012 at 0:47 Comment(2)
do We need to decorate this all optional properties ?Circumference
@KaushikThanki no you dont need toGeodesic
V
3

This worked for me, a simple solution, just using .net without any third party: https://mcmap.net/q/392860/-require-one-field-or-another

Like this:

public class EditModel
{
    public string ISBN { get; set; }
    public string ISBN13 { get; set; }

   [RegularExpression("True|true", ErrorMessage = "At least one field must be given a value")]    
   public bool Any => ISBN != null || ISBN13 != null;
}

Also good to know is that you can add any attributes to the properties in the model, like MinLength, MaxLength, etc. Just do not add the Required attribute.

Volgograd answered 20/10, 2021 at 6:22 Comment(1)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewInhibitory

© 2022 - 2024 — McMap. All rights reserved.