如何使用 FluentValidation 进行条件验证

How to do conditional validation with FluentValidation

我正在尝试使用 FluentValidation 进行自定义验证,这取决于我对象上的另一个 属性。

pos.Menge是小数,还有pos.Preis

RuleFor(pos => pos)
.Custom((pos, context) =>
{
    if(pos.Menge < 10000 && MathExtensions.GetDecimalPlaces(pos.Preis) > 2)
    {
        context.AddFailure(new ValidationFailure(nameof(pos.Preis), "Bei Mengen unter 10000 darf der Preis maximal 2 Nachkommastellen haben."));
    }
    else if(pos.Menge >= 10000 && MathExtensions.GetDecimalPlaces(pos.Preis) > 4)
    {
        context.AddFailure(new ValidationFailure(nameof(pos.Preis), "Der Preis darf maximal 4 Nachkommastellen haben."));
    }
});

此验证在提交表单时有效。但是,我的 属性 没有显示验证消息。它仅在 ValidationSummary 中可见。此外,更改值时不会触发验证。只有 OnSubmit.

有人知道我该如何解决这个问题吗?

就有条件地应用验证规则来进行比例精度检查而言,以下 LINQPad 示例可能适合。我正在使用比例精度来执行您的 MathExtensions.GetDecimalPlaces(pos.Preis) 检查,并使用 When 根据另一个 属性.

的值来确定何时应用该规则
void Main()
{
    var validator = new FooValidator();

    Console.WriteLine(validator.Validate(new Foo() { Bar = 1000.001m, Baz = 1 }).Errors?.Select(x => x.ErrorMessage));
    Console.WriteLine(validator.Validate(new Foo() { Bar = 1000.00001m, Baz = 10001 }).Errors?.Select(x => x.ErrorMessage));
}

public class Foo
{
    public decimal Bar { get; set; }
    public decimal Baz { get; set; }
}

public class FooValidator : AbstractValidator<Foo>
{
    public FooValidator()
    {
        RuleFor(foo => foo.Bar).ScalePrecision(2, int.MaxValue).WithMessage("Bei Mengen unter 10000 darf der Preis maximal 2 Nachkommastellen haben.").When(foo => foo.Baz < 10000);
        RuleFor(foo => foo.Bar).ScalePrecision(4, int.MaxValue).WithMessage("Der Preis darf maximal 4 Nachkommastellen haben.").When(foo => foo.Baz >= 10000);
    }
}

我不知道完整的用例,所以 YMMV。 Custom 规则 will not work 具有开箱即用的客户端验证,也不会缩放精度,但如果您编写自己的适配器,则可以支持它。我不完全确定填充的模型状态是否也会发挥作用,但以上是我要开始的地方;我发现支持的最佳结果是在没有其他选项时使用自定义验证器。