如何使用 FluentValidation .net 6 抛出异常?

问题描述 投票:0回答:1

我将我的 web api 从 asp net core 3.1 迁移到 .net 6,我在使用 FluentValidation 库时遇到了一些问题。

RuleFor(x => x.Name)
            .NotEmpty()
            .OnFailure(x =>
            {
                var message = "El nombre del Usuario es requerido.";
                throw new HttpException(message, message, (int)HttpStatusCode.BadRequest);
            })
            .Length(1, 150)
            .OnFailure(x =>
            {
                var message = "El nombre del Usuario debe contener hasta máximo 150 caracteres.";
                throw new HttpException(message, message, (int)HttpStatusCode.BadRequest);
            });

此代码过去可以正常工作,但是,当我更新库时,不推荐使用 .OnFailure() 方法。

我想知道如何像以前那样为每个 OnFailure 抛出自定义异常,其中 HttpException 是继承自 Exception 的自定义类。 json 结果的一个例子是:

    {
  "developerMessage": "El nombre del Usuario es requerido..",
  "userMessage": "El nombre del Usuario es requerido.",
  "errorCode": 400,
  "moreInfo": ""
   }

更新

我关注了这篇文章https://www.tutorialspoint.com/what-is-use-of-fluent-validation-in-chash-and-how-to-use-in-chash。我使用 CascadeMode.Stop 因为前一个已弃用,但是当我尝试测试 .Lenght 验证时,结果变量显示每个 RuleFor() 的第一个错误。我的意思是:如果我有 3 个 RuleFor() 并且每个规则有 2 个验证器,结果变量显示每个 RuleFor() 的第一个错误消息的验证器并且没有真正失败的错误消息。

我该如何解决这个问题?

public UserValidator()
{
  RuleFor(x => x.Name)
                .Cascade(CascadeMode.Stop)
                .NotEmpty().WithMessage("El nombre del Usuario es requerido.")
                .Length(1, 150).WithMessage("El nombre del Usuario debe contener hasta máximo 150 caracteres.");

  var result = Validate(new User()); //I need to get the context (user) to validate it , **not new User()**
        if(!result.IsValid)
        {
            foreach(var error in result.Errors)
            {
                var message = $"{error.ErrorMessage}";
                throw new HttpException(message, message, (int)HttpStatusCode.BadRequest);
            }
        }
}
c# .net asp.net-web-api fluentvalidation
1个回答
0
投票

您可以使用继承自

ValidateAndThrow
类的验证类的
AbstractValidator<T>
方法

在你的情况下,因为你想抛出

HttpException
异常,你必须覆盖验证类的
RaiseValidationException
方法,以便它们可以抛出所需的异常。

有两种方法可以做到这一点:

1 - 为每个验证类重写

RaiseValidationException
方法:

public class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(x => x.Name)
            .Cascade(CascadeMode.Stop)
            .NotEmpty()
            .WithMessage("El nombre del Usuario es requerido.")
            .Length(1, 150)
            .WithMessage("El nombre del Usuario debe contener hasta máximo 150 caracteres.");
    }

    // Add this override on your validation class
    protected override void RaiseValidationException(ValidationContext<IntegrateAccountingOfficeWithAsaasCommand> context, ValidationResult result)
    {
        var firstError = result.Errors[0];

        var ex = new HttpExcpetion(firstError.ErrorMessage, (int)HttpStatusCode.BadRequest);

        throw ex;
    }
}

2 - 创建一个方法覆盖的抽象类,这样就不需要重新实现每个验证类:

public abstract class CustomAbstractValidator<T> : AbstractValidator<T>
{
    protected override void RaiseValidationException(ValidationContext<IntegrateAccountingOfficeWithAsaasCommand> context, ValidationResult result)
    {
        var firstError = result.Errors[0];

        var ex = new HttpExcpetion(firstError.ErrorMessage, (int)HttpStatusCode.BadRequest);

        throw ex;
    }
}

public class UserValidator : CustomAbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(x => x.Name)
            .Cascade(CascadeMode.Stop)
            .NotEmpty()
            .WithMessage("El nombre del Usuario es requerido.")
            .Length(1, 150)
            .WithMessage("El nombre del Usuario debe contener hasta máximo 150 caracteres.");
    }
}

实现后,只需获取您的验证器实例并调用

ValidateAndThrow
方法:

1 - 没有依赖注入:

public class YourProgramFlowClass
{
    public void YourMethod()
    {
        // ... before validation code

        var validator = new UserValidator();

        validator.ValidateAndThrow(user);

        // ... after validation code
    }
}

2 - 没有依赖注入:

public class YourProgramFlowClass
{
    private readonly IValidator<ClassToValidate> _validator;

    public YourProgramFlowClass(IValidator<ClassToValidate> validator)
    {
        _validator = validator;
    }

    public void YourMethod()
    {
        // ... before validation code

        _validator.ValidateAndThrow(user);

        // ... after validation code
    }
}
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.