Search code examples
c#asp.net-coreerror-handlingmiddlewarefluentvalidation

How to rethrow Fluent Validation exception


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.


Solution

  • 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;
            }
        }