我想知道是否可以在FluentValidations验证器中更新某些可选参数的已验证模型,以防这些参数无效?
下面是一些代码:
public class Customer
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
public class CustomerValidator : AbstractValidator<Customer>
{
public CustomerValidator()
{
RuleFor(customer => customer.FirstName).NotNull().Length(5, 100);
RuleFor(customer => customer.LastName).NotNull().Length(5, 100);
RuleFor(customer => customer.MiddleName).Length(5, 100).When(c => string.IsNullOrWhiteSpace(c.MiddleName));
}
}
我像这样使用它:
Customer customer = new Customer { FirstName = "first name", LastName = "last name" };
CustomerValidator validator = new CustomerValidator();
var result = validator.Validate(customer);
Console.WriteLine(result.IsValid);
因此,就我而言,我想在中间名无效时将其设置为 null,并将警告保存在变量中,但仍将模型视为有效。
更新传递给验证的对象不是一个好主意,验证器应该只验证输入实体,并返回验证结果,仅此而已。我建议你有两个验证器。一个用于业务关键规则,一个用于警告,因此,如果第一个验证器返回该模型无效,则返回结果,如果没有严重错误,则验证警告,然后您可以决定是否继续并操作您的模型! 例如
public class Customer
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
public class CustomerCriticalValidator : AbstractValidator<Customer>
{
public CustomerValidator()
{
RuleFor(customer => customer.FirstName).NotNull().Length(5, 100);
RuleFor(customer => customer.LastName).NotNull().Length(5, 100);
}
}
public class CustomerWarningValidator : AbstractValidator<Customer>
{
public CustomerValidator()
{
RuleFor(customer => customer.MiddleName).Length(5, 100).When(c => string.IsNullOrWhiteSpace(c.MiddleName));
}
}
然后在代码中
Customer customer = new Customer();
CustomerCriticalValidator criticalValidator = new CustomerCriticalValidator();
CustomerWarningValidator warningValidator = new CustomerWarningValidator();
var validationResult = criticalValidator.Validate(customer);
if (validationResult.IsValid)
{
var result = warningValidator.Validate(customer);
if (!result.IsValid)
{
//DO what you need with customer
}
}
实际上,操作传入的值不仅仅是验证。 所以FluentValidator可能不是最好的地方。 如何将该特定逻辑放入二传器中?
string middleName;
public string MiddleName {
get => middleName;
set {
middleName =
value.Length < 5 || value.Length > 100
? null
: value;
}
编辑:回应评论中提出的问题
因此,关于您希望显示警告消息。 我假设你已经知道如何在FluentValidation中做到这一点。 这似乎是一个不太有趣的话题,至少当我查找此资源时。 因此,我将在此响应中省略实际的警告逻辑。
但是,为了给你一个战斗机会发出这样的警告,你需要把它存储在某个地方。 因此,只需为此添加一个字段并在您的 setter 逻辑中处理它:
public string middleNameWarning;
string middleName;
public string MiddleName {
get => middleName;
set {
if (value.Length < 5 || value.Length > 100) {
middleName = null;
middleNameWarning =
$"'{value}' is not a valid MiddleName. It was reset to null. "
+ "Set MiddleName explicitly to a valid value to remove this warning.";
}
else {
middleName = value;
middleNameWarning = null;
}
}
}
middleNameWarning
必须是公开的,以便您使用FluentValidation访问它(我能够确认这一点(。 如果你不喜欢这样,也许你可以有一个方法访问它。 此外,它可能只是一个布尔值,当您发现其值为 true 时,您可以将文本设置在其他地方。
最后,为了确认您原来的方法可能不会像您希望的那样奏效,我在 GitHub 存储库上发现了一个封闭的问题,有人询问如何做类似的事情。 以下是JeremySkinner的回应:
嗨,FluentValidation 只对预填充的对象执行验证,它不会修改/更改属性的值。从技术上讲,您可以使用完成这项工作的自定义验证器来执行此操作,但我并不真正推荐它。
我已经设法解决了它:
public class CustomerValidator : AbstractValidator<Customer>
{
public CustomerValidator()
{
RuleFor(customer => customer.FirstName).NotNull().Length(5, 100);
RuleFor(customer => customer.LastName).NotNull().Length(5, 100).OnAnyFailure((customer) =>
{
customer.LastName = null;
customer.Warnings.Add(nameof(customer.LastName));
});
RuleFor(customer => customer.MiddleName).Length(5, 100).When(c => string.IsNullOrWhiteSpace(c.MiddleName));
}
}