如何重新抛出 Fluent Validation 异常

How to rethrow Fluent Validation exception

如何在 FluentValidation 之后运行ErrorHandlingMiddleware

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

并且在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);
        }

所以现在 FluentValidation 错误后 ErrorHandlingMiddleware 没有执行。

在 AbstractValidator 中有 ThrowOnFailures {get; initonly set;} 因此对于这种情况我们将更改 ThrowOnFailures 但我们不能。

所以我得到了另一个解决方案。

AbstractValidator class中有Validate方法,你可以看到下面的代码。

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

我们需要更改 context.ThrowOnFailures 或删除它。

所以我的解决方案。

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