FluentValidation : https://github.com/JeremySkinner/FluentValidation
關於為何要使用,因為微軟自帶的模型驗證有點弱,還需要自己去寫一大堆的驗證。
關於asp.net core的集成 我用的是 FluentValidation.AspNetCore nuget
直接在addmvc后添加 AddFluentValidation() 就好了
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddFluentValidation();
我一般用反射注入msdi
// 注冊 Validator var types = assembly.GetTypes().Where(p => p.BaseType != null && p.BaseType.GetInterfaces().Any(x => x == typeof(IValidator))); foreach (var type in types) { if (type.BaseType != null) { var genericType = typeof(IValidator<>).MakeGenericType(type.BaseType.GenericTypeArguments[0]); services.AddTransient(genericType, type); } }
然后這里例舉一些比較常用的方法
以下是我的模型 。
public class UserInput { public string CustomerId { get; set; } public string UserName { get; set; } public string PhoneNumber { get; set; } public string FullName { get; set; } public string Description { get; set; } public string UnionId { get; set; } public string Email { get; set; } public string Password { get; set; } }
這里是我的validator
public class UserInputVaildator : AbstractValidator<UserInput> { public UserInputVaildator() { RuleFor(m => m.UserName).NotEmpty().WithMessage("登錄名是必須的"); RuleFor(m => m.CustomerId).NotEmpty().WithMessage("客戶Id是必須的"); //當手機號為空的時候就不會再去驗證手機號格式是否 因為默認是不會停止驗證。 RuleFor(m => m.PhoneNumber) .Cascade(CascadeMode.StopOnFirstFailure) .NotEmpty().WithMessage("手機號是必須的") .PhoneNumber().WithMessage("手機格式不正確"); //這里的意思是當 郵箱不為空時采取驗證郵箱格式是否正確 RuleFor(m => m.Email) .EmailAddress().When(m => !string.IsNullOrWhiteSpace(m.Email)).WithMessage("郵箱格式不正確"); } }
當然,還有一些其他的東西
public class TestInput { public string Grant { get; set; } public int Number { get; set; } }
public class TestInputValidator : AbstractValidator<TestInput> { public TestInputValidator() {
RuleSet("test", () => { RuleFor(m => m.Number).GreaterThan(0).WithMessage("Number要大於0"); }); RuleFor(m => m.Grant).NotEmpty().WithMessage("Grant不能為空"); } }
規則的設置,可以適應不同的驗證場景,對同一個Model進行不同的驗證
[Route("api/[controller]")] [ApiController] public class TestController : ControllerBase { // [HttpGet] public IActionResult Get([FromQuery]TestInput input) { return Ok(); } //規則的設置,可以適應不同的驗證場景,對同一個Model進行不同的驗證 [HttpPost] public IActionResult Index([FromBody][CustomizeValidator(RuleSet = "test")]TestInput input) { return Ok("213"); } }
父類,接口的驗證
public class CustomerCreateInput : ClientInput, ICustomerInput{ //具體的實現接口 } public class CustomerInputInterfaceValidator : AbstractValidator<ICustomerInput>{ //具體 接口 驗證邏輯 } public class ClientInputVaildators : AbstractValidator<ClientInput>{ //集體 基類 驗證邏輯 } //那么我該如果重用接口和基類的驗證邏輯 public class CustomerCreateInputValidator : AbstractValidator<CustomerCreateInput> { public CustomerCreateInputValidator() { //只需要包含進來 Include(new CustomerInputInterfaceValidator()); Include(new ClientInputVaildators()); } }
這里就有個問題,如果包含的驗證類中包含了 RuleSet,那么該如何啟用。因為默認不會啟用,這個問題,我也不知道 (~ ̄▽ ̄)~ 只能說我也不太精通,昨天剛剛開始用。