最近在作Web API,用到了流式驗證,就簡單的說說這個流式驗證。express
首先咱們定義一個Filter,以下ide
1學習 2ui 3this 4spa 5code 6blog 7繼承 8接口 9 10 11 |
public class ValidateResponseFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) { if (!actionContext.ModelState.IsValid) { //actionContext.ModelState.Keys actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState); } } } |
重寫Action執行方法,若是請求model存在異常,則將500error返回給客戶端。
接下來咱們要怎麼作,定義一個BaseController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
[ValidateResponseFilter] public class BaseController : ApiController { protected HttpResponseMessage CreateSystemErrorResponse( string errorMsg) { return Request.CreateResponse< object >( new { IsSuc = false , ErrorMsg = errorMsg }); } protected HttpResponseMessage CreateErrorResponse( string responseCode, Type type = null , HttpStatusCode statusCode = HttpStatusCode.OK) { return Request.CreateResponse< object >(statusCode, new { IsSuc = false , ErrorMsg = MessageResHelper.GetMessage(type != null ? type.Name : this .GetType().Name, responseCode) }); } protected HttpResponseMessage CreateSucResponse( string responseCode = "" ) { if ( string .IsNullOrEmpty(responseCode)) { return Request.CreateResponse< object >( new { IsSuc = true }); } return Request.CreateResponse< object >( new { IsSuc = true , ErrorMsg = MessageResHelper.GetMessage( this .GetType().Name, responseCode) }); } } |
在BaseController上咱們標記上面的Attribute,驗證不經過進行請求攔截,而後全部的APIController都繼承BaseController,這樣全部繼承自BaseController的Controller都會走驗證。
接下來咱們看一下Request的定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class CustomerValidateRequest : IValidatableObject { private readonly IValidator _validator; public CustomerValidateRequest() { _validator = new CustomerValidateRequestValidator(); } public string Email { get ; set ; } public string Password { get ; set ; } public string ValidateCode { get ; set ; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { return _validator.Validate( this ).ToValidationResult(); } } |
Request定義好以後,咱們在最下面寫方法獲取驗證的結果。接下來再看看咱們的Validator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class CustomerValidateRequestValidator : AbstractValidator<CustomerValidateRequest> { public CustomerValidateRequestValidator() { RuleFor(dto => dto.Email).NotNull().NotEmpty(); RuleFor(dto => dto.Password).NotNull().NotEmpty(); RuleFor(dto => dto.ValidateCode).NotNull().NotEmpty().Length(WebAppSettings.ValidateCodeLength); When(dto => ! string .IsNullOrWhiteSpace(dto.Email), () => { RuleFor(c => c.Email).Matches( @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$" ); }); } } |
在這裏就是咱們所要驗證的邏輯,能夠驗證最基本的非空,長度,還能夠驗證正則。這裏RuleFor返回的是以下的接口類型
1 |
public IRuleBuilderInitial<T, TProperty> RuleFor<TProperty>(Expression<Func<T, TProperty>> expression) |
該接口繼承IRuleBuilder接口
1 |
public interface IRuleBuilderInitial<T, out TProperty> : IFluentInterface, IRuleBuilder<T, TProperty>, IConfigurable<PropertyRule, IRuleBuilderInitial<T, TProperty>> |
IRuleBuild有不少擴展方法在DefaultValidatorExtensions類中,以下
簡直是太多了,驗證信用卡,郵箱,比較大小,區域,不等於等等,固然你本身也能夠擴展一些出來。
咱們用Google DHC看一下效果
若是什麼都不傳,就會根據上面的驗證規則進行驗證。
若是傳了Email,則會驗證Email是否正確。
最後記得在Globle.asax.cs中增長以下代碼,注意在Nuget中找到FluentValidation和FluentValidation.MVC
1 2 3 4 |
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false ; ModelValidatorProviders.Providers.Add( new FluentValidationModelValidatorProvider( new AttributedValidatorFactory())); ValidatorOptions.CascadeMode = CascadeMode.StopOnFirstFailure; FluentValidationModelValidatorProvider.Configure(); |
結束語
免費學習更多精品課程,登陸樂搏學院官網http://h.learnbo.cn/
本文出自 「技術創造價值」 博客,請務必保留此出處http://leelei.blog.51cto.com/856755/1788944