I'm using IValidatableObject to validate a complex object in the following scenario.
public class Foo {
[Required]
public Bar Foobar { get; set; }
}
public class Bar : IValidatableObject {
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
// check if the current property instance is decorated with the Required attribute
if(TheAboveConditionIsTrue) {
// make sure the Name property is not null or empty
}
}
}
I don't know if this is the best way to do this, if not I'm happy to take comments on other ways of solving the validation.
Create an abstract base class for Foo
that implements IValidatableObject
and make its Validate()
method virtual:
public abstract class FooBase : IValidatableObject
{
public string OtherProperty { get; set; }
public Bar Foobar { get; set; }
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var results = new List<ValidationResult>();
//Validate other properties here or return null
if (String.IsNullOrEmpty(OtherProperty))
results.Add(new ValidationResult("OtherProperty is required", new[] { "OtherProperty" }));
return results;
}
}
Now implement your base class as either FooRequired
or FooNotRequired
:
public class FooRequired : FooBase
{
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var result = base.Validate(validationContext).ToList();
result.AddRange(Foobar.Validate(validationContext));
return result;
}
}
public class FooNotRequired : FooBase
{
//No need to override the base validate method.
}
Your Bar
class would still look something like this:
public class Bar : IValidatableObject
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var results = new List<ValidationResult>();
if (String.IsNullOrEmpty(Name))
results.Add(new ValidationResult("Name is required", new[] { "Name" }));
return results;
}
}
Usage:
FooBase foo1 = new FooRequired();
foo1.Validate(...);
FooBase foo2 = new FooNotRequired();
foo2.Validate(...);