LA.NET [EN]

Apr 24

After started looking at the S#arp framework, I was almost obliged to take a look at NHibernate Validator framework .To see if it was really that good, I decide to pick a small example and apply some validation rules. This post contains some notes on my incursion into this framework.

The first thing you need to do is to download the library and add a reference to in your project. Then, you can start adding validation rules to the properties of your objects. Currently, you have three options: you can use attributes and decorate your fields/properties with the available attributes, or you can use an XML file to define those rules or you can define those rules by using a fluent interface approach. We’ll start by exemplifying attribute usage. Take a look at the following snippet:

namespace TestApp {
    public class Student    {
        public Student( Int32 studentId ) {
            StudentId = studentId;
        }

        [Min(1, Message="StudenId must be positive")]
        public int StudentId { get; private set; }
        [NotEmpty (Message="Name cannot be empty"), NotNull(Message="Name cannot be null")]
        public String Name { get; set; }
        [Email(Message="Email is not correct")]
        public String Email { get; set; }
    }
}

As you can see, we’re using several of the validation attributes and we’re also specifying an error message for all of them. You are now in a position to validate an instance of Student by using the ValidatorEngine class:

var invalidId = -1;
var student = new Student( invalidId ) {
           Name = "Luis",
           Email = "labreu@"
};

var validator = new ValidatorEngine( );
var invalidValues = validator.Validate( student );
foreach ( var invalidValue in invalidValues ) {
    Console.WriteLine( "Property: {0} —- PropertyPath:{1} —– Message: {2}n",
                    invalidValue.PropertyName,
                    invalidValue.PropertyPath,
                    invalidValue.Message );
}

If you run the previous snippet,you should get errors for the Student’s Id and email properties!

As I said, you can also specify the validation rules by using XML files. Here are the validation rules written on a xml file:

<?xml version="1.0" encoding="utf-8" ?>
<nhv-mapping xmlns="urn:nhibernate-validator-1.0" namespace="TestApp" assembly="TestApp">
  <class name="Student">
    <property name="StudentId">
      <min value="0" message="StudenId must be positive" />
    </property>
    <property name="Name">
      <not-empty message="Name cannot be empty" />
      <not-null message="Name cannot be null" /> 
    </property>
    <property name="Email">
      <email message="Email is not correct" />
    </property>
  </class>
</nhv-mapping>

Now, you have two options: you can embed the XML file or just copy it to same place on the disk (generally, you’ll put them on the same folder as the app). In both cases, you’ll need to pass a config options to the ValidatorEngine object. Here’s the code you might use when you’re using an external config file (do notice that if the config file is embedded, you’ll still need to set the ValidatorMode property):

using Environment = NHibernate.Validator.Cfg;

//more code

var configOptions = new NHVConfigurationBase( );
configOptions.Mappings.Add( new MappingConfiguration( "Student.nhv.xml" ) );
configOptions.Properties[Environment.Environment.ValidatorMode] = ValidatorMode.UseExternal.ToString( );
var validator = new ValidatorEngine( );
validator.Configure( configOptions );
var invalidValues = validator.Validate( student );
//same code as before for showing error msgs

You should also keep one more thing in mind (if you decide to go with the embedded resource approach): if you want to get automatic loadding, then you should give the file the same name that you gave to the class.

Before ending, there’s still time for showing one last option for setting up the rules: using a fluent configuration style. If you prefer this approach, the first thing you need to do is create a class for the  definition. Here’s how it looks:

public class StudentRules : ValidationDef<Student> {
   public StudentRules( ) {
                Define( st => st.StudentId ).GreaterThanOrEqualTo( 1 ).WithMessage( "StudenId must be positive" );
                Define( st => st.Name ).NotEmpty( ).WithMessage( "Name cannot be empty" )
                    .And.NotNullable( ).WithMessage( "Name cannot be null" );
                Define( st => st.Email ).IsEmail( ).WithMessage( "Email is not correct" );
    }
}

And then, you can load your rules like this:

FluentConfiguration fluentConfig = new FluentConfiguration( );                                 
fluentConfig.Register<StudentRules, Student>( )
                                    .SetDefaultValidatorMode( ValidatorMode.UseExternal );

var validator = new ValidatorEngine( );
validator.Configure( fluentConfig );
//the rest remains the same

I won’t say anything more about this framework today. The only thing I’ll add is that I did enjoy it and I‘ll come back to it in the future (especially because it does integrate really well with NH and I’ll be talking about that and S#arp framework in a near future).

2 comments so far

  1. art
    12:12 pm - 11-27-2009

    hey thanks

    i”m banging my head trying to get the ddl generation from SchemaExport integrated with these attributes

    should they be picked up?

  2. w3cvalidation
    11:45 am - 5-12-2010

    Nice information, I really appreciate the way you presented.Thanks for sharing..