Creating a generic validation framework

Recently in a few discussions of system architecture I have brought up adamant complaints about coupling validation logic to your domain objects. This weekend Thomas Mayfield contacted me on how I would go about implementing this in a domain driven designed system. Initially I got sidetracked over what tool I would use for my rules engine and I’ve still not concluded which would be best so I went about creating my Validation layer and decided to leave the specific details of creating validation logic for later.

As always I start with an interface. In this case it ends up being a very simple interface.

public interface IValidator<T>
    ValidationResult Validate(T obj);
    ValidationResult Validate(T obj, bool suppressWarnings);

Basically I want this service to take in an object and validate it, and then return to me whether it’s valid and any warnings or error messages associated with the validation. Which lead me to creating a ValidationResult class (in lieu of the similarly named class in the Enterprise Library validation block).

First I created a very simple ValidationMessage class:

public sealed class ValidationMessage
    public string Message { get; internal set; }
    public bool Warning { get; internal set; }

    //Only allow creation internally or by ValidationResult class.
    internal ValidationMessage()

The ValidationResult class is a little more complex:

public sealed class ValidationResult
    private bool _dirty = true;
    private bool _valid;

    public bool Valid
            //theoretically O(n) time but in pratice will be constant time
            //Still, no need for multiple traversals, Traverse only if it's changed
            if (_dirty)
                _valid = Messages.FirstOrDefault(msg => msg.Warning == false) == null;
                _dirty = false;

            return _valid;

    public ValidationResult()
        Messages = new List<ValidationMessage>();

    public IList<ValidationMessage> Messages { get; internal set; }

    /// <summary>
    /// Adds the error. 
    /// </summary>
    /// <param name="errorMessage">The error message.</param>
    public void AddError(string errorMessage)
        _dirty = true;
        Messages.Add(new ValidationMessage {Message = errorMessage});

    /// <summary>
    /// Adds the warning. 
    /// </summary>
    /// <param name="warningMessage">The warning message.</param>
    public void AddWarning(string warningMessage)
        //No need to mark collection dirty since warnings never generate validation changes
        Messages.Add(new ValidationMessage {Message = warningMessage, Warning = true});

Basically the only tricks to this class is that I only allow the creation of the internal list of ValidationMessages to be handled by the same assembly. I also appended factory methods to allow manual insertion of errors or warnings. The reason for this is in my workings with EntLib VAB was that the results were inflexible in letting me append some messages myself and then roll the results down to the screen. This resulted in me having to create marshaling classes to just transfer the messages from the results to a collection that I could add more information to.

Implementing a concrete validator, the EmployeeValidator:

public class EmployeeValidator : IValidator<Employee>
    #region Implementation of IValidation<Employee>

    public ValidationResult Validate(Employee employee)
        return Validate(employee, false);

    public ValidationResult Validate(Employee employee, bool suppressWarnings)
        var result = new ValidationResult();

        //This code here would be replaced with a validation rules engine later

        if (employee != null)
            if (!suppressWarnings && employee.HireDate > DateTime.Now)
                result.Messages.Add(new ValidationMessage {
                    Message = string.Format("Employee hire date: {0} is set in the future.", employee.HireDate),
                    Warning = true});

            if (employee.Person != null)
                if (string.IsNullOrEmpty(employee.Person.FirstName))
                    result.Messages.Add(new ValidationMessage {Message = "Employee FirstName is required."});
                if (string.IsNullOrEmpty(employee.Person.LastName))
                    result.Messages.Add(new ValidationMessage {Message = "Employee LastName is required."});
                result.Messages.Add(new ValidationMessage {Message = "Employee person data is missing."});
            result.Messages.Add(new ValidationMessage {Message = "Employee data is missing."});

        return result;


Nothing really complicated goes on here just simple very basic validation code that rolls in error messages if needed. This area here would be replaced by a ruleset engine later on, for myself atleast. Otherwise you could do any validation you wanted here.

Now to actually validate your objects I created a ValidationFactory method also simliar to the VAB.

public static class ValidationFactory
    public static ValidationResult Validate<T>(T obj)
            var validator = ObjectFactory.GetInstance<IValidator<T>>();
            return validator.Validate(obj);
        catch (Exception ex)
            var messages = new List<ValidationMessage> {new ValidationMessage {
                Message = string.Format("Error validating {0}", obj)}};


            var result = new ValidationResult {Messages = messages};
            return result;

    private static IEnumerable<ValidationMessage> FlattenError(Exception exception)
        var messages = new List<ValidationMessage>();
        var currentException = exception;

            messages.Add(new ValidationMessage {Message = exception.Message});
            currentException = currentException.InnerException;
        } while (currentException != null);

        return messages;

Once again beauty comes with simplicity I take advantage of StructureMap to handle my dependency injection with the GetInstance method. Then just call Validate. I added a helper method that will allow me to roll out a complex exception message (most likely it’d only ever be you forgot to register a validator for some type) if any occur.

Registering this for StructureMap is extremely simple inside you registry setup for SM you would just add


And then onto a quick usage example

public void InvalidEmployeeTest()
    var employee = new Employee {Person = new Person {FirstName = string.Empty, LastName = string.Empty}};

    var results = ValidationFactory.Validate(employee);

    Assert.IsTrue(results.Messages.Count > 0);

At this point you have en entirely decoupled validation framework that will allow you to validate your objects with any kit, ruleset engine, or static validation you wish. Now if you wondered where I would put this in my architecture I would have it validate at the presenter level right after the screen scrape of data.

public bool SaveEmployee()
    var employee = View.Employee;

    var results = ValidationFactory.Validate(employee);

    if (results.Valid)
        View.Errors = results.Messages;

kick it on

Shout it


30 thoughts on “Creating a generic validation framework

  1. cool post.

    Maybe consider adding an extension method for the model objects being validated, so the code is a bit more intuitive, where:
    var results = ValidationFactory.Validate(employee);
    var results = employee.Validate();

  2. Thank you all for your positive feedback!

    @Rinat, yes your validation framework would work quite well in this architecture all you would need to do is replace my basic if/else validation logic in EmployeeValidator : IValidator with your framework. You would most likely need to alter my ValidationFactory.Validate method to take in a string for a RuleSet name. I realized this after my post that I forgot to allow a string to switch which ruleset(s) are applied but it’s a minor change.

    @Jax, I agree that is a good idea since it still gives you pure domain driven design and it gives you the transparency/simplicity that coupling gives without any of the costs of maintaining the coupled code.

    @Alessandro .FirstOrDefault is an extension method provided on IEnumerable by LINQ, it’s equivalent of doing:
    (from message in Messages
    where message.Warning == false
    select message).FirstOrDefault();

    It returns the first instance in the IEnumerable collection from that linq statement, if the collection has no items (would be when there are 0 errors) it will return default(Employee) which would be null. I suppose I could’ve done

    _valid = Messages.Count(msg => msg.Warning == false) == 0;

    Either would produce the same end result.

  3. Thanks for your excelent topic!

    The validation framework you provided and my company validation framework (used in Spring and J2EE) are the same. I’ve thought that i would implement it in dot Net. But you’ve done.

    By the way, if you have time, plz look at SharpArch project of wmccaferrty, in his project he implement another validation framework that use NHibernate.Validator library. It’s a very good framework!

    Thank you!

  4. I like the framework but why are you against having business rules as part of your business object.
    Help me understand. At first glance it sounds like you are setting yourself up for a Maintenance nightmare. What happens when you have multiple clients?

    “I would have it validate at the presenter level right after the screen scrape of data.” That sounds like a bad idea to me. Everywhere you use your business obect your presentation layer needs to know how to validate it. Yikes..

  5. @Joe, I’m against have my business rules apart of my business objects because it breaks the separation of concerns methodology. This is the exact reason why Persistence Ignorance is important for data layers or object relational mappers my business objects shouldn’t know anything about my DAL/ORM for the same reason they shouldn’t know how I validate them. When you couple your objects to either a validation framework or a DAL this is when you have a maintenance nightmare.

    I stand behind my comment about validating my objects at the presenter level. It’s where it makes the most sense since then I can directly pass the ValidationResult.Messages collection right back to the UI and display what’s wrong with the objects. If you place the Validation further up either in the controller or DAL layer how do you return what’s wrong? Do you throw an exception with the ValidationResult attached to it? Do you require everyone of your controller/DAL methods to take ValidationResult out parameter? Now your violating separation of concerns across every layer of your application above the presenter layer since it has to have some type of knowledge of the ValidationResults class. If you go with the throwing an exception route now you need to try/catch every single operation at the Presenter layer and then figure out some way to display the list error messages in a meaningful way. Perhaps if you created a custom error class that in the constructor took the ValidationResults class or the ValidationResults.Messages collection and you do try/catch(ValidationError err) as a way to get the messages out of it would be a good trade off.

    Another solution would be to create multiple rule sets one that’s an absolute minimum for persistence requirements otherwise you’ll get database exceptions like string length <= 200 and then have a call to the validation framework inside the DAL which will throw more meaningful exceptions instead of a raw database exception. Then you have the call to the validation framework at the Presenter level also for more robust rules. This would make sense to me since then if you had sometime of batch service or external source sending you objects you would be able to save them as long as they met the lowest level of acceptance and then be able to clean/fix the data later.

    Besides in my opinion it makes the most sense to validate the data immediately after the screen scrape anyway since you most likely have already done the most basic validation having max length attributes on your text boxes, setting up regular expression validators to scrub invalid characters and then you pass off the object to the validation framework to have it pass true business rules.

    I see no reason why any of this would become a maintenance nightmare since you would still have all your business rules contained in classes that implement IValidator which could either call out to an external rules engine like Windows Workflow Foundation RuleSet engine for example or just call into static rules inside the class. If you have alot of common rules you could easily put them in separate class files and instantiate rules objects inside the concrete IValidator classes or make the classes have static methods and just call out to the objects.

  6. @Joe, Presentation layer does not need to have any reference to rules in order to validate them in a strongly-typed and a user-friendly manner.

    @dotnetchris, it is advised not to do any try-catch handling in the validation or splitting up the rules into different rule sets (complexifies everything). Just allow the rules to write to the IScope with the property path and then wire this information right to the UI. See

  7. @Rinat I fully agree with you I think the try/catch method of passing validation exceptions back to the UI is a poor design decision. I won’t go as far as to say terrible design decision since I reserve that for coupling your validation right into your business objects.

    On the second point about the rule sets I don’t necessarily agree with you on that. Having multiple rule sets makes alot of sense if you have different rules for example on inserting a new record vs updating an existing record. Another case would be say you have more stringent rules for a customer placing an order on your public website but that internal sales people can manipulate an order with more flexibility that would trigger a validation error for the public website.

    The other main case is when you receive data from external systems, when you receive data from external systems I think it’s good to have 2 rule sets one for the data requirements of your system and the 2nd for the minimum validation required to insert data to your database that won’t throw an exception (string is too long, column can’t be null etc). I always believe whenever you receive data from an external system you should always be able to save it regardless of whether it’s valid or not since it’s always possible to fix bad data however it’s almost impossible to recreate data that never existed in the first place.

  8. @dotnetchris,

    I agree with the point of having different rule sets for the domain areas or operations that logically are different (i.e.: insert vs. update). For example new object must have “scope.Validate(() => customer.ID, Is.Default)”, while existing object being update should be “scope.Validate(() => customer.ID, Is.NotDefault)”

    I just didn’t agree with the idea of splitting the rules based on their application area (i.e. persistence vs. presentation). If the context is the same, then same rules should be applied. And I definitely think that the idea of using UI-level validators (like RegEx validators, or required field validators etc) is just way too inefficient. Validation should happen in the rules, instead of being scattered all around the place (validation failures or warnings could be routed to the input controls then). This way, when you change the rule in one place, you don’t have to change anything else.

    What do you think?

  9. @Rinat, I agree with you the only time I would have separate rules for presentation vs persistence is if I did have a source for external data since even if it’s invalid I’d always want to save the data and then respond to them that it’s invalid but I’d still always want to be able to keep the raw data.

    For the UI validations, I think it’s worth having them because there’s no need for the server to apply complex rule validation to your objects when some one enters 1 in for a SSN field or @#$ as a name. As much as I love ASP.NET and server side programming it’s pointless to make the server do extra work when it can be done on the client side. The server will still need to do the validation anyway since you can never trust the client 100% but atleast when it makes it past the client validation it’s much more likely to pass business validation or fail on real rule violations not just that a name or a field has invalid characters.

    This just goes back to my point that having the validation done in the presentation layer is where it should be since I disagree Joe that it would be a maintenance nightmare if you can’t expect your development team to remember to do if(Validate(object)) then Save(object) else ShowErrors() there’s a much larger problem there that no framework will ever be able to fix.

  10. It seems the right way to do validation, but I would also agree with dotnetchris that sometimes you can have serveral validation rules.
    In my current project, I must validate entries that can be persisted with minimum validation, but that need to be validated against stricter rules to be activated.
    Sometimes a specific validation is requiered to enable some actions.

    I usually use minimal UI validation, mostly to avoid number parsing exceptions.

  11. @Harold

    Thanks for your comment! Yes I have an application that has this, it’s on my assembla page and you can download the source code over SVN or get a zip file with the source. If you have any problems send me an email and I’ll send you the source code myself.

    • Can you send me either a link or the zipfiles for Creating a generic validation framework?

      I can’t find it on your assembla page.


      • Russ,

        Go there and click the download button and it will create a zip for you of the source code. The code you are looking for is under the validation folder. The StructuredWeb project depends on PostSharp so there’s 2 things you can do either go in and comment out the BusinessConversation class and any where that attribute exists and the solution will build or you can just take a look at the Validation / ValidationTest projects seperately.

        If you have any issues getting it now or any questions don’t hesitate to contact me!

  12. object validation is nice, but isn’t what we really need is input validation. for instance, user posts a form, which is just really a collection of strings. so if one of those strings represents, for instance february 30th, your validation wouldn’t really be able to handle that, would it? because it would never make it into ‘the object’. Data Annotations work pre object instantiation. but they force you to muck up your poco’s. have you thought of a validation framework for input validation that could server as an alternative to data annotations?

    • For wire request validation as opposed to actual business validation (that might require loading related data from the database, or logic that’s far beyond simple is valid date, string length not too long, quantity greater than zero). For request validation i find data annotations / fluent annotation with a decorated model to be perfect. These types are also great for generating a swagger api definition from (swashbuckle for huge out of box support

      However at this point i’m also doing stuff where my systems just accept json directly as loose type Dictionary or List<Dictionary. This is in somewhat explatory stages, i haven’t decided what path would be best to go down for request validation. I haven’t decided if i want to just piggy back on top of fluent validator, Shouldly / fork of Shouldly, or just some simple helper extension methods

    • That’s definitely a thing. Me and clojure are not friends, that’s not a path I’d ever want to be on. But great to hear that it’s working out for you. And yes I wasn’t really expecting to see i had an unapproved comment on my blog on this post. It’s very disappointing to me that even almost 7 years after i wrote this post I still don’t feel like there’s an absolute solution to validation. There’s lots of partial solutions, but still so much needs done to cobble them together to have end to end business validation not merely simple request DTO validation. Thankfully request DTO validation has been solved several times over with many flavors to pick your poison.

Leave a Reply to HoangDung, Le Cancel reply

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

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

Google photo

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

Twitter picture

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

Facebook photo

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

Connecting to %s