dotNetChris @ Marisic.Net

February 11, 2009

Creating a generic validation framework

Filed under: Architecture, Programming, StructuredWeb — dotnetchris @ 10:25 pm

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
    {
        get
        {
            //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."});
            }
            else
                result.Messages.Add(new ValidationMessage {Message = "Employee person data is missing."});
        }
        else
            result.Messages.Add(new ValidationMessage {Message = "Employee data is missing."});

        return result;
    }

    #endregion
}

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)
    {
        try
        {
            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)}};

            messages.AddRange(FlattenError(ex));

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

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

        do
        {
            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

ForRequestedType<IValidator<Employee>>().TheDefaultIsConcreteType<EmployeeValidator>();

And then onto a quick usage example

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

    var results = ValidationFactory.Validate(employee);

    Assert.IsNotNull(results);
    Assert.IsFalse(results.Valid);
    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)
        _controller.SaveEmployee(employee);
    else
        View.Errors = results.Messages;
}

kick it on DotNetKicks.com

Shout it

BloggingContext.ApplicationInstance.CompleteRequest();

About these ads

26 Comments »

  1. Creating a generic validation framework…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

    Trackback by DotNetShoutout — February 12, 2009 @ 2:16 pm

  2. Hi

    That’s a nice post.

    I’m wondering, can your framework provide support for this .NET Business Rules and Validation App Block?
    http://abdullin.com/journal/2008/11/23/net-application-block-for-validation-and-business-rules.html

    I’m mostly interested in strongly-typed binding of errors to UI.

    Regards

    Comment by Rinat Abdullin — February 13, 2009 @ 5:55 am

  3. 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);
    becomes:
    var results = employee.Validate();

    Comment by Jax — February 13, 2009 @ 6:11 am

  4. Good example.

    What this the implementation if FirstOrDefault?

    Thanks.

    Comment by Alessandro Cavalieri — February 13, 2009 @ 8:28 am

  5. [...] Creating a generic validation framework – Chris Marisic walks through the construction of a nice straightforward decoupled validation framework that makes use of generics [...]

    Pingback by Reflective Perspective - Chris Alcock » The Morning Brew #286 — February 13, 2009 @ 8:29 am

  6. Creating a generic validation framework « dotNetChris @ Marisic.Net…

    DotNetBurner.com – news and articles about .net DotNetBurner…

    Trackback by Creating a generic validation framework « dotNetChris @ Marisic.Net - DotNetBurner — February 13, 2009 @ 10:31 am

  7. 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.

    Comment by dotnetchris — February 13, 2009 @ 2:31 pm

  8. Thanks a lot for the post. Nice work!!

    Comment by Pradeep Kumar Mishra — February 13, 2009 @ 5:29 pm

  9. 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!

    Comment by HoangDung, Le — February 14, 2009 @ 1:11 am

  10. 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..

    Comment by Joe — February 14, 2009 @ 6:45 pm

  11. @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.

    Comment by dotnetchris — February 14, 2009 @ 10:32 pm

  12. @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 http://abdullin.com/journal/2009/1/29/ddd-and-rule-driven-ui-validation-in-net.html

    Comment by Rinat Abdullin — February 15, 2009 @ 7:28 am

  13. @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.

    Comment by dotnetchris — February 15, 2009 @ 9:00 am

  14. @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?

    Comment by Rinat Abdullin — February 15, 2009 @ 11:31 am

  15. [...] 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 …Continue [...]

    Pingback by Cross Site Scripting » Blog Archive » Creating a Generic Validation Framework « Dotnetchris @ Marisic.Net — February 15, 2009 @ 6:33 pm

  16. @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.

    Comment by dotnetchris — February 15, 2009 @ 8:52 pm

  17. 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.

    Comment by Think Before Coding — February 19, 2009 @ 10:22 pm

  18. [...] Creating A Generic Validation Framework [...]

    Pingback by Links 2009-02-24 - Gunnar Peipman's ASP.NET blog — February 24, 2009 @ 10:22 am

  19. hello!

    This looks very nice.. is there any sample app available that impliments this approach?

    Thanks
    Harold

    Comment by Harold Chattaway — April 15, 2009 @ 8:45 pm

  20. @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.

    Comment by dotnetchris — April 16, 2009 @ 12:02 am

    • 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

      Comment by Russ — September 5, 2009 @ 5:14 am

      • Russ,

        http://code.assembla.com/MarisicDotNet/subversion/nodes/StructuredWeb/StructuredWeb

        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!

        Comment by dotnetchris — September 5, 2009 @ 3:07 pm

  21. Great! I made some enhancements to it to use it in a project. thanks!

    Comment by Lord Of Wings — August 31, 2009 @ 10:59 am

    • LoW, that’s great to hear! I’m glad it was able to help you, and make it fit for your development that’s exactly why I wrote this article.

      Comment by dotnetchris — September 1, 2009 @ 12:15 pm

  22. Once I read this article http://vitana-group.com/article/microsoft-.net/validation and now use it in my projects. It is really flexible and because of validation definition in the external file we allow very customize it per our client.

    Comment by John — May 20, 2010 @ 9:53 am

  23. nice and thx for sharing your solution!!!

    Comment by myro — February 6, 2012 @ 11:24 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 243 other followers

%d bloggers like this: