How to set multiple error messages for different scenarios in the Custom validation attribute?

I'm just dealing with custom validation attributes, and I'm trying to write a custom validation attribute that will be placed at the class level to check for several properties of my model.

I can access all the properties of my model, and I want to be able to check several conditions in my IsValid overload and report it, having different error messages as follows (simplified example).

public override bool IsValid(object value) { var model = (MyObject) value; //if this value is set, I don't want to do anything other checks if (model.Prop3) { return true; } if (model.Prop1 == "blah" && model.Prop2 == 1) { ErrorMessage = "you can't enter blah if prop 2 equals 1"; return false; } if(model.Prop1 == "blah blah" && model.Prop2 == 2) { ErrorMessage = "you can't enter blah blah if prop 2 equals 2"; return false; } return true; } 

But when I do this, I get an exception the first time that ErrorMessage refers to "Cannot set property more than once.

Now I could split my user attribute into several user attributes, but I hoped there would be one way to do this in one, otherwise I would repeat β€œcatch all” in each

 //if this value is set, I don't want to do anything other checks if (model.Prop3) { return true; } 

I already had a search, but I could not find anything, so I apologize if I miss anything obvious.

early!

+4
source share
2 answers

Interest Ask! I can come up with two approaches to this. Therefore, not the right decisions based on what you want, but they can help reuse your code. It is not possible to create an abstract CustomAttribute class named MyCustomAttribute (or something else) that overrides IsValid as follows:

 public override bool IsValid(object value) { var model = (MyObject) value; //if this value is set, I don't want to do anything other checks if (model.Prop3) { return true; } CustomValidate(model); } 

CustomValidate(MyObject model) is your abstract method, then you can write several custom attribute classes that extend MyCustomAttribute, and you just need to implement validation logic for a specific scenario.

So you can have two classes:

 public class BlahCustomAttribute : MyCustomAttribute { public override Boolean CustomValidate(MyObject obj) { if (model.Prop1 == "blah" && model.Prop2 == 1) { ErrorMessage = "you can't enter blah if prop 2 equals 1"; return false; } } } public class BlahBlahCustomAttribute : MyCustomAttribute { public override Boolean CustomValidate(MyObject obj) { if (model.Prop1 == "blah" && model.Prop2 == 1) { ErrorMessage = "you can't enter blah blah if prop 2 equals 1"; return false; } } } 

Hope this helps - not exactly what you wanted, but also do the work and its cleanliness.

Another solution is a comma - separate error messages in the ErrorMessage property and process them in the interface (but I would go with the first approach).

+1
source

In MVC4, you can override IsValid to return different messages as a ValidationResult

 public class StrongPasswordAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext context) { if (value == null) return new ValidationResult("Password is required"); var val = value.ToString(); if (!Regex.Match(val, @"^(?=.*[az]).{0,}$").Success) { return new ValidationResult("Password must contain at least one lower case letter"); } if (!Regex.Match(val, @"^(?=.*[AZ]).{0,}$").Success) { return new ValidationResult("Password must contain at least one UPPER case letter"); } if (!Regex.Match(val, @"^(?=.*\d).{0,}$").Success) { return new ValidationResult("Password must contain at least one number"); } return ValidationResult.Success; } } 
+3
source

All Articles