在 FluentValidation9.2之后,如果我们的对象的某一个属性是基础类型或者接口,哪我们可以用它的子类或者实现类的验证器来验证这个接口,或者基类。
例如
// 我们有一个表示联系信息的接口
// 例如在一个CRM系统当中 所有的联系实体必须有一个名字和Email.
public interface IContact
{
string Name { get; set; }
string Email { get; set; }
}
// 个人 还有一个生日信息
public class Person : IContact
{
public string Name { get; set; }
public string Email { get; set; }
public DateTime DateOfBirth { get; set; }
}
// 组织
// 有一个额外的总部地址
public class Organisation : IContact
{
public string Name { get; set; }
public string Email { get; set; }
public Address Headquarters { get; set; }
}
// 我们打算效验的模型
public class ContactRequest
{
public IContact Contact { get; set; }
public string MessageToSend { get; set; }
}
接下来我们来为Person和Organisation创建验证器
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(x => x.Name).NotNull();
RuleFor(x => x.Email).NotNull();
RuleFor(x => x.DateOfBirth).GreaterThan(DateTime.MinValue);
}
}
public class OrganisationValidator : AbstractValidator<Organisation>
{
public OrganisationValidator()
{
RuleFor(x => x.Name).NotNull();
RuleFor(x => x.Email).NotNull();
RuleFor(x => x.HeadQuarters).SetValidator(new AddressValidator());
}
}
现在我们给ContactReqeust
. 来创建一个验证器。使用SetInheritanceValidator
我们可以为Contact运行时的实际类型指定验证器。如下
public class ContactRequestValidator : AbstractValidator<ContactRequest> \
{
public ContactRequestValidator()
{
RuleFor(x => x.Contact).SetInheritanceValidator(v =>
{
v.Add<Organisation>(new OrganisationValidator());
v.Add<Person>(new PersonValidator());
});
}
}
public class Base
{
public string BaseName { get; set; }
}
public class Derived1 : Base
{
public string Derived1Name { get; set; }
}
public class Derived2 : Base
{
public string Derived2Name { get; set; }
}
// 基础类的验证器
public class BaseValidator<T> : AbstractValidator<T> where T : Base
{
public BaseValidator()
{
RuleFor(b => b.BaseName).NotNull();
}
}
// 第一个子类的验证器
public class Derived1Validator : BaseValidator<Derived1>
{
public Derived1Validator():base()
{
RuleFor(d => d.Derived1Name).NotNull();
}
}
// 第二个子类的验证器
public class Derived2Validator : BaseValidator<Derived1>
{
public Derived2Validator():base()
{
RuleFor(d => d.Derived2Name).NotNull();
}
}