Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning multiple ValidationExceptions

Been trying to incorporate server side DataAnnotation validation to my project and I've found out that DataAnnotations has it's own type of error, the ValidationException. My problem with it, though, is that it only returns one validation error at a time so if 3 properties failed validation only the first one is thrown. I'm looking for a way to throw all of the errors as an exception so instead of informing the user/developer that the validation failed, it would state which properties/fields failed validation at one go.

I found the Validator.TryValidateObject(...) method but it just populates ValidationResults and leaves the developer an option to throw and exception or not. What I currently implement is iterating through the ValidationResults to create a list of ValidationExceptions from that, wrap the list into an AggregateException then throw another ValidationException with the AggregateException in its InnerExceptions.

ValidationContext validationContext = new ValidationContext(entity, null, null);
List<ValidationResult> validationResults = new List<ValidationResult>();

bool isValid = Validator.TryValidateObject(entity, validationContext, validationResults, true);

if (!isValid)
{
      List<ValidationException> validationErrors = new List<ValidationException>();
      foreach (ValidationResult validationResult in validationResults)
      {    
           validationErrors.Add(new ValidationException(validationResult.ErrorMessage);
      }

      throw new ValidationException("Entity validation failed.", new AggregateException(validationErrors));
}

So basically, my questions would be:

  1. Is there a reason why there's no built in way to throw multiple errors at the same time? That is, am I missing some best practice with DataAnnotation Validations?
  2. Is there a better way to achieve what I was trying to implement?
  3. Also... how can I include the member name when wrapping the ValidationResult into a ValidationException?
like image 884
iamnobody Avatar asked Feb 24 '14 08:02

iamnobody


1 Answers

Answer your first question: Because each validation attribute have their own IsValid property and return public ValidationResult(string errorMessage, IEnumerable<string> memberNames); validation result and you can get member name from list of member name. So each validation failed of property return isValid. It is not a good idea that the entity has validation you are applying on property of entity.

Answer your second question: You can create your own ValidationAttribute list to validate entity:

var validationResults = new List<ValidationResult>();
var validationAttributes = new List<ValidationAttribute>();
validationAttributes.Add(new CustomValidationAttribute(typeof(ClaimValidator), "ValidateClaim"));
var result = Validator.TryValidateValue(claimObject,
                                        new ValidationContext(claimObject, null, null),
                                        validationResults,
                                        validationAttributes);

Third Answer: You can get the member name from ValidationResult:

public ValidationResult(string errorMessage, IEnumerable<string> memberNames)
like image 138
Thakur Rock Avatar answered Nov 10 '22 23:11

Thakur Rock