3

好的,假设我正在尝试根据枚举的值有条件地验证对象,我该怎么做?

这是验证对象的示例调用。

MyObjectValidator validator = new MyObjectValidator();
ValidationResult results = validator.Validate(new MyObject());

这是具有枚举值的类的示例。

public class MyObjectValidator : AbstractValidator<MyObject>
{

    public MyObjectValidator()
    {
        RuleFor(x => x.anEnum).Equal(MyObject.MyEnum.First).SetValidator(new FirstValidator());
    }

}

public class FirstValidator : AbstractValidator<MyObject>
{

    public FirstValidator()
    {
        RuleFor(x => x.someDecimal).Equal(1).WithMessage("Decimal must equal 5 with anEnum set to First");
    }

}

public class MyObject
{

    public enum MyEnum : int
    {
        First = 0,
        Second = 1,
        Third = 2
    }

    public decimal someDecimal { get; set; }
    public MyEnum anEnum { get; set; }

    public MyObject()
    {
        anEnum = MyEnum.First;
        someDecimal = 5;
    }
}

此特定示例引发消息:“验证器 'FirstValidator' 无法验证 'MyEnum' 类型的成员 - 类型不兼容。”

经过一些编辑,我想出了一个包装器来做我希望的事情,但我更喜欢一个更优雅的解决方案。我将 MyObjectValidator 替换为

public MyObjectValidator()
{
    RuleFor(x => x.anEnum).SetValidator(new ValidatorWrapper<MyObject>()).When(x => x.anEnum == MyObject.MyEnum.First);
}

并添加了一个验证器包装器

public class ValidatorWrapper<T> : PropertyValidator
{

    public ValidatorWrapper() : base("Validator Message")
    {
    }

    protected override bool IsValid(PropertyValidatorContext context)
    {
        MyObject myObj = (MyObject)context.Instance;
        FirstValidator validator = new FirstValidator();
        ValidationResult results = validator.Validate(myObj);
    }
}

有没有办法在不必提供 propertyvalidator 包装器的情况下引用内部上下文,以便我可以根据枚举值有条件地验证许多规则?

4

2 回答 2

5

您看到的错误(“验证器 'FirstValidator' 无法验证 'MyEnum' 类型的成员 - 类型不兼容”)是因为通过使用 SetValidator 您正在尝试使用 FirstValidator 验证 anEnum属性(只能验证MyObject 的实例) - 这不是正确的方法。如果要基于 enum 属性触发规则,则需要使用 FluentValidation 对条件的支持。

如果您只有一个要应用条件的规则,那么您可以这样做:

public class MyObjectValidator : AbstractValidator<MyObject> {

  public MyObjectValidator() {
      RuleFor(x => x.someDecimal).Equal(1).When(x => x.anEnum == MyObject.MyEnum.First);
  }

}

...或者,如果您想将相同的条件应用于多个规则,您可以使用顶级 When 方法使用单个条件:

public class MyObjectValidator : AbstractValidator<MyObject> {

    public MyObjectValidator() {
        When(x => x.anEnum == MyObject.MyEnum.First, () => {
            RuleFor(x => x.someDecimal).Equal(1);
            //other rules can go here
        });
    }

}
于 2011-11-16T17:02:15.870 回答
0

您正在使用 CLR Object.Equals(),您需要使用Equal()或库提供的任何其他内容。

于 2011-11-15T18:59:37.820 回答