Since you want multiple fields to be part of the validation attribute, it is much easier to pass an array of parameters to the constructor of the RequiredIf attribute and loop through the fields to make logic. I did something similar and here is the code.
For making simple, I used single constructor and thus I have to pass array even for a single field, but this can be changed.
For validating model, I am passing array of fields as below:
[RequiredIf(new string[] {"Year", "Make"})]
The IsValid method simply goes through the fields and checks. Null checking happens within the validation logic.
Let me know for any questions.
Here are the associated codes.
public String Year { get; set; }
[RequiredIf(new string[] {"Year"})]
public String Make { get; set; }
[RequiredIf(new string[] {"Year", "Make"})]
public String Model { get; set; }
public String Trim { get; set; }
public class RequiredIfAttribute : ValidationAttribute
{
private const string DefaultErrorMessageFormatString = "The {0} field is required.";
private readonly string[] _dependentProperties;
public RequiredIfAttribute(string[] dependentProperties)
{
_dependentProperties = dependentProperties;
ErrorMessage = DefaultErrorMessageFormatString;
}
protected override ValidationResult IsValid(Object value, ValidationContext context)
{
Object instance = context.ObjectInstance;
Type type = instance.GetType();
foreach (string s in _dependentProperties)
{
Object propertyValue = type.GetProperty(s).GetValue(instance, null);
if (propertyValue == null || value != null)
{
return ValidationResult.Success;
}
}
return new ValidationResult(context.DisplayName + " required. ");
}
}