Reputation: 3240
Ok, let's say I'm trying to validate an object conditionally based upon the value of an enum, how can I do that?
Here's a sample call to validate the object.
MyObjectValidator validator = new MyObjectValidator();
ValidationResult results = validator.Validate(new MyObject());
Here's a sample of a class with an Enum Value.
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;
}
}
This particular example throws the message: "The validator 'FirstValidator' cannot validate members of type 'MyEnum' - the types are not compatible."
After some editing, I came up with a wrapper to do what I'm hoping, but I'd prefer a more elegant solution. I replaced MyObjectValidator with
public MyObjectValidator()
{
RuleFor(x => x.anEnum).SetValidator(new ValidatorWrapper<MyObject>()).When(x => x.anEnum == MyObject.MyEnum.First);
}
And added a validator wrapper
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);
}
}
Is there a way to reference the inner context without having to provide the propertyvalidator wrapper such that I can conditionally validate a number of rules based upon an enum value?
Upvotes: 3
Views: 4533
Reputation: 1461
The error you're seeing ("The validator 'FirstValidator' cannot validate members of type 'MyEnum' - the types are not compatible") is because by using SetValidator you're trying to validate the anEnum property with FirstValidator (which can only validate instances of MyObject) - this isn't the correct approach. If you want to trigger rules based on the enum property, you need to use FluentValidation's support for conditions.
If you've only got a single rule to which you want to apply the condition, then you can do this:
public class MyObjectValidator : AbstractValidator<MyObject> {
public MyObjectValidator() {
RuleFor(x => x.someDecimal).Equal(1).When(x => x.anEnum == MyObject.MyEnum.First);
}
}
...alternatively, if you want to apply the same condition to multiple rules, you can use a single condition using the top-level When method:
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
});
}
}
Upvotes: 5
Reputation: 16651
You're using the CLR's Object.Equals()
, you need to use Equal()
or whatever else the library provides.
Upvotes: 0