1

How to run ErrorHandlingMiddleware after FluentValidation?

  services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest)
                .AddJsonOptions(options =>
                {
                    options.JsonSerializerOptions.IgnoreNullValues = true;
                }).AddFluentValidation(fv =>
                {
                    fv.RegisterValidatorsFromAssemblyContaining<LoginValidator>();
                    fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
                });
            app.UseMiddleware<ErrorHandlingMiddleware>();

And in ErrorHandlingMiddleware

private static string HandleMessage(Exception exception)
        {
            var responseModel = exception switch
            {           
                ValidationException validationException => new ErrorResponseModel
                {
                    Type = ApiErrorType.Validation,
                    MainMessage = ErrorMessage.ValidationError,
                    Messages = validationException.Errors.Select(x => x.ErrorMessage)
                },
                AuthorizationException or AuthenticationException => new ErrorResponseModel
                {
                    Type = ApiErrorType.Authorization, MainMessage = ErrorMessage.AuthorizationAuthenticationError
                },
                _ => new ErrorResponseModel {Type = ApiErrorType.Global, MainMessage = ErrorMessage.GlobalError}
            };

            return JsonSerializer.Serialize(responseModel);
        }

So now after FluentValidation error ErrorHandlingMiddleware does not executed.

  • Try to set the `RunDefaultMvcValidationAfterFluentValidationExecutes` attribute to `true`, if we set the attribute value to `false`, the FluentValidation is the only validation library that executes. See [Compatibility with ASP.NET’s built-in Validation](https://docs.fluentvalidation.net/en/latest/aspnet.html#compatibility-with-asp-net-s-built-in-validation). – Zhi Lv Feb 19 '21 at 03:27
  • @ZhiLv thanks for the comment, but don't work –  Feb 19 '21 at 07:37

1 Answers1

2

In AbstractValidator have ThrowOnFailures {get; initonly set;} so for that case we will change ThrowOnFailures but we can't.

So I get another solution.

In AbstractValidator class have Validate method and there you can see the following piece of code.

if (!result.IsValid && context.ThrowOnFailures) 
{
   RaiseValidationException(context, result);
}

We need to change context.ThrowOnFailures or remove it.

So my solution.

 public abstract class AbstractValidatorCustom<T> : AbstractValidator<T>
    {
     
        /// <summary>
        /// Validate
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override ValidationResult Validate(ValidationContext<T> context)
        {
            var validationResult = base.Validate(context);

            if (!validationResult.IsValid)
            {
                RaiseValidationException(context, validationResult);
            }

            return validationResult;
        }
    }