我将用这个例子来解释解决方案。我将验证此联系人实体:
public class Contact
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
}
要求是验证 FirstName 和 LastName,然后是 Address1、Address2、City、PostalCode,并且可以在其他实体中重用我们的验证器。
创建接口来定义特定实体是什么。
public interface IAmPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
public interface IHaveAddress
{
string Address1 { get; set; }
string Address2 { get; set; }
string City { get; set; }
string PostalCode { get; set; }
}
现在联系人实体必须实现这两个接口:
public class Contact : IAmPerson, IHaveAddress
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
}
然后,为 IAmPerson 实体创建第一个验证器
public class PersonValidator : AbstractValidator<IAmPerson>
{
public PersonValidator()
{
RuleFor(data => data.FirstName).Length(3, 50).WithMessage("Invalid firstName");
RuleFor(data => data.LastName).Length(3, 50).WithMessage("Invalid LastName");
}
}
IHaveAddress 实体的第二个
public class AddressValidator : AbstractValidator<IHaveAddress>
{
public AddressValidator()
{
RuleFor(data => data.Address1).NotNull().NotEmpty().WithMessage("Invalid address1");
RuleFor(data => data.Address2).NotNull().NotEmpty().WithMessage("Invalid address2");
RuleFor(data => data.City).NotNull().NotEmpty().WithMessage("Invalid City");
RuleFor(data => data.PostalCode).NotNull().NotEmpty().WithMessage("Invalid PostalCode");
}
}
自定义验证器的使用方式
public class ContactValidator: AbstractValidator<Contact>
{
public ContactValidator()
{
RuleFor(contact => contact).SetValidator(new PersonValidator());
RuleFor(contact => contact).SetValidator(new AddressValidator());
}
}
现在您可以使用您的验证器来验证任何其他实体中的个人数据或地址数据。您需要做的唯一事情是在您要验证的实体中实现特定的接口。
[更新]
您可以通过添加扩展方法来提高代码的可读性
public static class ValidatorExtensions
{
public static IRuleBuilderOptions<T, IHaveAddress> MustHaveAValidAddress<T>(this IRuleBuilder<T, IHaveAddress> ruleBuilder)
{
return ruleBuilder.SetValidator(new AddressValidator());
}
public static IRuleBuilderOptions<T, IAmPerson> MustBeAValidPerson<T>(this IRuleBuilder<T, IAmPerson> ruleBuilder)
{
return ruleBuilder.SetValidator(new PersonValidator());
}
}
这是使用我刚刚添加的扩展方法的最终结果:
RuleFor(contact => contact).MustBeAValidPerson();
RuleFor(contact => contact).MustHaveAValidAddress();