Validating Classes using Data Annotations

We’ve been beefing up our validation routines recently as it became clear that we needed to add a lot more protection to our Validation Engines in our NetCore project.

We use EFCore Code-First to generate our database in which we have a large number of Data Annotations such as:

    public string Surname { get; set; }

Our testers have started really getting into min/max testing so they’ve been happily trying to put oversized data into all of our fields, and guess what? We’re seeing Internal Server Errors all over the place.

So we’ve been faced with a challenge about where to implement our validation and how and even what level. Whilst investigating solutions, I realized that we can re-use the same Data Annotations on our EF Entities as part of our validation routines, which means that in addition to our more complicated business logic, we can check for things such as Surname being less than 50 characters, all using generics.

Below is a sample function which will work with any class marked up with Data Annotations and add them to a custom class we use for catching and reporting validation errors. The key points to note here are the ValidationContext and TryValidateObject().

            var modelValidator = new ValidationContext(toValidate);
            var modelFailures = new List<ValidationResult>();
            if (!Validator.TryValidateObject(toValidate, modelValidator, modelFailures, validateAllProperties: true))
                foreach (var failure in modelFailures)
                    foreach (var memberName in failure.MemberNames)
                        result.ValidationErrors.Add(memberName, failure.ErrorMessage);

We then convert the ValidationErrors class into a ModelState so that we can return a 400 error.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: