如何使用 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 具有开箱即用的客户端验证,也不会缩放精度,但如果您编写自己的适配器,则可以支持它。我不完全确定填充的模型状态是否也会发挥作用,但以上是我要开始的地方;我发现支持的最佳结果是在没有其他选项时使用自定义验证器。
我正在尝试使用 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 具有开箱即用的客户端验证,也不会缩放精度,但如果您编写自己的适配器,则可以支持它。我不完全确定填充的模型状态是否也会发挥作用,但以上是我要开始的地方;我发现支持的最佳结果是在没有其他选项时使用自定义验证器。