1

I have a validation class:

public sealed class ValidationSet : ValidationAttribute
{
    private List<string> _set = new List<string>();
    public ValidationSet(params string[] setOfValues)
    {
        _set = setOfValues.ToList();
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (!(_set.Select(s => s.ToLower()).Contains(value.ToString().ToLower())))
        {
            throw new Exception("not in the set");
        }
        return ValidationResult.Success;
    }
}

and here is how I use it:

public class Car
{
    [ValidationSet("honda", "gm")]
    public string CarMake{ get; set; }

}

When I instantiate the Car class by:

...
Car c = new Car();
c.CarMake = "ford";
...

Nothing will happen and if I print c.CarMake, it shows ford - the validation didn't happened.

I am just wondering what do I miss here.

Thanks!

jamesdeath123
  • 4,268
  • 11
  • 52
  • 93
  • Have you confirmed the validation code actually gets called? – Andrew Mar 21 '14 at 19:13
  • What are you doing to call the validation code? Attributes don't actually *do* anything on their own: they're like metadata. You have to tell some bit of code to do something with the properties marked with `ValidationSet`; nothing will magically cause it to execute on its own. – eouw0o83hf Mar 21 '14 at 19:14
  • @Andrew I tried to throw exception in the attribute's constructor and it didn't happen, so I guess it is not get called; the problem is: why it is not get called and what is missing? – jamesdeath123 Mar 21 '14 at 19:14
  • FWIW I tested your IsValid method and it works, if you put a breakpoint does it get hit? – Eric Scherrer Mar 21 '14 at 19:15
  • @eouw0o83hf hmmm it is probably the problem but I don't know how to solve it - I thought adding the attribute will do the work when the property is set? – jamesdeath123 Mar 21 '14 at 19:18

2 Answers2

3

Just instantiating the class and assigning the field is not going to call IsValid, you need to use the class in a framework that examines Car, sees that it has ValidationAttribute on CarMake and will call IsValid.

In this example asp:DynamicValidator is doing the work:

How to: Customize Data Field Validation

Eric Scherrer
  • 3,328
  • 1
  • 19
  • 34
  • I see. It works different from what I expect. Is it any other way to validate the property on the fly, so that if I do car.Make = "ford", it will throw the error? I mean another way to do it other then do it in the property's setter. thanks! – jamesdeath123 Mar 21 '14 at 19:26
  • 1
    I have had great success using a framework called [FluentValidation](http://fluentvalidation.codeplex.com/) – Eric Scherrer Mar 21 '14 at 19:31
1

I would look into FluentValidation. You can create a validator class for Car.

public class CarValidator : AbstractValidator<Car>
{
    public CarValidator() {
        RuleFor(m => m.CarMake).Equal("gm").Equal("honda");
    }
}

Usage:

var car = new Car { CarMake = "honda" };
var validator = new CarValidator();
if (validator.Validate(car).IsValid)
    // car is valid
Neil Smith
  • 2,565
  • 1
  • 15
  • 18