Use custom validation responses with fluent validation

前端 未结 4 1229
天命终不由人
天命终不由人 2020-12-29 12:46

Hello I am trying to get custom validation response for my webApi using .NET Core.

Here I want to have response model like

[{
  ErrorCode:
  ErrorFi         


        
4条回答
  •  醉酒成梦
    2020-12-29 13:15

    In .net core you can use a combination of a IValidatorInterceptor to copy the ValidationResult to HttpContext.Items and then a ActionFilterAttribute to check for the result and return the custom response if it is found.

    // If invalid add the ValidationResult to the HttpContext Items.
    public class ValidatorInterceptor : IValidatorInterceptor {
        public ValidationResult AfterMvcValidation(ControllerContext controllerContext, ValidationContext validationContext, ValidationResult result) {
            if(!result.IsValid) {
                controllerContext.HttpContext.Items.Add("ValidationResult", result);
            }
            return result;
        }
    
        public ValidationContext BeforeMvcValidation(ControllerContext controllerContext, ValidationContext validationContext) {
            return validationContext;
        }
    }
    
    // Check the HttpContext Items for the ValidationResult and return.
    // a custom 400 error if it is found
    public class ValidationResultAttribute : ActionFilterAttribute {
        public override void OnActionExecuting(ActionExecutingContext ctx) {
            if(!ctx.HttpContext.Items.TryGetValue("ValidationResult", out var value)) {
                return;
            }
            if(!(value is ValidationResult vldResult)) {
                return;
            }
            var model = vldResult.Errors.Select(err => new ValidationErrorModel(err)).ToArray();
            ctx.Result = new BadRequestObjectResult(model);
        }
    }
    
    // The custom error model now with 'ErrorCode'
    public class ValidationErrorModel {
         public string PropertyName { get; }
         public string ErrorMessage { get; }
         public object AttemptedValue { get; }
         public string ErrorCode { get; }
    
         public ValidationErrorModel(ValidationFailure error) {
             PropertyName = error.PropertyName;
             ErrorMessage = error.ErrorMessage; 
             AttemptedValue = error.AttemptedValue; 
             ErrorCode =  error.ErrorCode;
         }
    }
    

    Then in Startup.cs you can register the ValidatorInterceptor and ValidationResultAttribute like so:

    public class Startup {
        public void ConfigureServices(IServiceCollection services) {
            services.AddTransient();
            services.AddMvc(o => {
                o.Filters.Add()
            });
        }
    }
    

提交回复
热议问题