如何使用FluentValidation.net6抛出异常?

hgb9j2n6  于 2023-05-08  发布在  .NET
关注(0)|答案(1)|浏览(256)

我将我的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 result的一个例子是:

{
  "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,因为前一个已经过时了,但是当我尝试testing .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);
            }
        }
}
nkoocmlb

nkoocmlb1#

您可以使用验证类的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<User> 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<T> 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
    }
}

相关问题