Nuget包導入FluentValidation.AspNetCore
官方的用法是在services中添加如下來操作
services.AddMvc().AddFluentValidation(config=> {
});
但是個人感覺這種把在驗證提示信息不是太友好,比如他的格式往往是這樣
多個都觸發的情況
因為這是后台觸發的驗證,拋開前端驗證不說,如果觸發api接口驗證后,提示出來上面的信息,在前端提示有點麻煩,因為后台還有可能出現錯誤情況或者其他失敗情況,格式跟錯誤格式不一樣,前端還要分別處理,所以處理起來不方便
這里我沒有使用上面的方式添加服務,通過前面文章中的注入,我自己注入了模型的驗證服務
重新封裝了下驗證觸發后的返回結果 統一封裝在OperatorResult類中,與接口本生發生錯誤返回的結果一致,這樣前端就不必為了區分驗證提示還是異常提示或者保存失敗提示,只需要提示封裝的信息即可
下面是我驗證類,關於ScopedDI屬性標簽在前面的文章中有介紹,這樣我不需要在ConfigServices中添加任何代碼了
[ScopedDI] public class SchoolDtoValidator : AbstractValidator<SchoolDto> { public SchoolDtoValidator() { RuleFor(x => x.Name).NotEmpty().WithMessage("學校名不能為空"); RuleFor(x => x.Address).NotEmpty().WithMessage("地址不能為空"); } }
接下來就是在Controller中DI上我們的驗證
IValidator<SchoolDto> _validator; /// <summary> /// 構造函數 /// </summary> /// <param name="validator"></param> public DemoController( IValidator<SchoolDto> validator) { _validator = validator; }
在相關業務代碼中處理下即可,前端只需要根據ResultType判斷,提示Message就行了
public async Task<IActionResult> CreateData([FromBody]SchoolDto model) { var result = new OperatorResult(ResultType.Fail); var validationResult = _validator.Validate(model); if (!validationResult.IsValid) { result.Message = string.Join(";", validationResult.Errors); return Ok(result); } try { var school = _mapper.Map<SchoolDto, School>(model); school.Id = Guid.NewGuid(); school.AddClassesDomain(new Classes { CName = "Demo", Id = Guid.NewGuid() }); var command = new DemoCreateCommand { com_school = school }; result = await _mediator.Send(command); } catch { result.Message = "操作失敗"; } return Ok(result); }