null对象的FluentValidation规则

Ber*_*ern 35 c# fluentvalidation

我一直在尝试创建一个FluentValidation规则,在验证它的属性之前检查它验证的对象的实例是否为null.

我宁愿在验证器中封装这个空验证,而不是在调用代码中执行它.

请参阅下面的示例代码以及需要所需逻辑的注释:

namespace MyNamespace
{
    using FluentValidation;

    public class Customer
    {
        public string Surname { get; set; }
    }

    public class CustomerValidator: AbstractValidator<Customer> 
    {
        public CustomerValidator() 
        {
            // Rule to check the customer instance is not null.

            // Don't continue validating.

            RuleFor(c => c.Surname).NotEmpty();
        }
    }

    public class MyClass
    {
        public void DoCustomerWork(int id)
        {
            var customer = GetCustomer(id);
            var validator = new CustomerValidator();

            var results = validator.Validate(customer);

            var validationSucceeded = results.IsValid;
        }

        public Customer GetCustomer(int id)
        {
            return null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是如何在CustomerValidator()构造函数中检查当前客户实例是否为null并且如果它为null则中止进一步的规则处理

提前致谢.

Mat*_*hew 29

您应该能够覆盖ValidateCustomerValidator班级中的方法.

public class CustomerValidator: AbstractValidator<Customer> 
{
    // constructor...

    public override ValidationResult Validate(Customer instance)
    {
        return instance == null 
            ? new ValidationResult(new [] { new ValidationFailure("Customer", "Customer cannot be null") }) 
            : base.Validate(instance);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我正在使用最新版本的FluentValidation,而Validate()甚至不会为我开火.这似乎不再可能. (4认同)
  • 从 8.1.3 ([link](https://github.com/JeremySkinner/FluentValidation/commit/820e9c3cbbec621c4e2b533cfca79edc6d73148b)) 开始,如果您想实现自定义逻辑,您似乎可以覆盖 `PreValidate()` 方法传递给验证器的空模型。 (3认同)
  • 此解决方案不再适用于新版本的 FluentValidation (3认同)

Pat*_*iek 16

我现在无法真正测试,但您可以尝试覆盖Validate,或在When块中包含规则:

public CustomerValidator()
{
     When(x => x != null, () => {
         RuleFor(x => x.Surname).NotEmpty();
         //etc.
     });
}
Run Code Online (Sandbox Code Playgroud)

  • @Bern也许你可以做 `RuleFor(x =&gt; x).NotNull().WithMessage("Customer does not exit");`,但在 `When` 块之外? (3认同)

Elm*_*mar 6

对于使用版本> 6.2.1的用户,您需要覆盖此签名,以实现与@chrispr相同的操作:

public override ValidationResult Validate(ValidationContext<T> context)
{
    return (context.InstanceToValidate == null) 
        ? new ValidationResult(new[] { new ValidationFailure("Property", "Error Message") })
        : base.Validate(context);       
}
Run Code Online (Sandbox Code Playgroud)

  • 这种方法既没有为WebApi解雇. (4认同)

cam*_*inc 6

这是一篇较旧的帖子,但想要更新答案以包含 FluentValidation 文档中的以下内容:

使用预验证

如果每次调用验证器时都需要运行特定代码,则可以通过覆盖 PreValidate 方法来实现。此方法采用 ValidationContext 和 ValidationResult,您可以使用它们来自定义验证过程。

public class MyValidator : AbstractValidator<Person> {
  public MyValidator() {
    RuleFor(x => x.Name).NotNull();
  }

  protected override bool PreValidate(ValidationContext<Person> context, ValidationResult result) {
    if (context.InstanceToValidate == null) {
      result.Errors.Add(new ValidationFailure("", "Please ensure a model was supplied."));
      return false;
    }
    return true;
  }
}
Run Code Online (Sandbox Code Playgroud)

https://fluentvalidation.net/start#using-prevalidate