There is a new framework in the NHibernate Contrib project named NHibernate.Validator. The project began as port of the java Hibernate.Validator project and is started by Dario Quintana. This framework allows you to validate objects in a similar way to other validation frameworks except that it has out of the box integration with the NHibernate's entity lifecycle. This means that you can configure it to do validation on entity insert/updates. The integration with NHibernate is not required however.

You can specify the validation rules either as property/field attributes directly in the code or in a separate xml file with a schema similar to that used in NHibernate mapping files.


public class User
  public virtual int Id
      get { return id; }

  [NotEmpty, NotNull]
  public virtual string UserName
      get { return userName; }
      set { userName = value; }

  public virtual string Email
      get { return email; }
      set { email = value; }

  public DateTime CreatedDate
    get { return createdDate; }
    set { createdDate = value; }

  [Min(18, Message="You are to young!")]
  public int Age
    get { return age; }
    set { age = value; }

  public string CreditCardNumber
    get { return creditCardNumber; }
    set { creditCardNumber = value; }

If you don't like to clutter your code with attributes you can use the xml config option, example:

<nhv-mapping xmlns="urn:nhibernate-validator-1.0">
  <class name="NHibernate.Validator.Demo.Winforms.Model.Customer, NHibernate.Validator.Demo.Winforms">    
    <property name="FirstName">
    <property name="Email">

    <property name="Zip">
      <pattern  regex="^[A-Z0-9-]+$" message="Examples of valid matches: 234G-34DA | 3432-DF23"/>
      <pattern  regex="^....-....$" message="Must match ....-...."/>

Personally I can barley stand the NHibernate xml mapping files (don't like to poke around in xml files that much) so I think I prefer the attribute version. But it is nice to have this option. It makes it possible to validate objects in third party assemblies that you do not have the code for. There are many more validators than the ones used above and it is very easy to create custom validators.

You can configure the validation engine in code or in app/web.config, this is how you can do it in code:

NHVConfiguration nhvc = new NHVConfiguration();
nhvc.Properties[Environment.ApplyToDDL] = "false";
nhvc.Properties[Environment.AutoregisterListeners] = "true";
nhvc.Properties[Environment.ValidatorMode] = "UseAttribute";
nhvc.Mappings.Add(new MappingConfiguration("NHibernate.ValidatorDemo.Model", null));

ValidatorEngine validator = new ValidatorEngine();

Since NHibernate.Validator uses the event listener system I think you have to use NHibernate 2.0 if you want the NHibernate integration. To validate an object you simply use the Validate function, here is a simple example (using MonoRail):

public void Create([DataBind("user")] User user)
  InvalidValue[] errors = validator.Validate(user);

  if (errors.Length > 0)
    Flash["errors"] = errors;

And here is the view:

    <h2>Create user</h2>    
    ${Html.FormToAttributed("Home", "Create", {@id: "create-form"})}
        <label for="UserName">UserName:</label>
        <label for="UserName">Email:</label>
    <?brail if IsDefined("errors"): ?>
        <?brail for error in errors: ?>
            <li>${error.PropertyName}: ${error.Message}</li>    
        <?brail end ?>
    <?brail end ?>

This is of course a very simple example. You probably want to have the error message after each field and some client based validation. I think I will do another post about trying to integrate NHiberante Validator with JQuery validation.

If you want to try NHibernate validator and do not want to build it from the trunk there is a 1.0 alpha release available on sourceforge. The release contains a WinForms examples that shows how to integrate it with the WinForms error provider system.


Anonymous said...

Cool, it looks similar to the validation for Castle ActiveRecord

pdu said...

Do you work for SNCB or Infrabel ?

Torkel Ödegaard said...

No, I am work for Cybercom Sweden, why do you ask?

pdu said...

SNCB/infrabel in belgium it's the belgium rail company. Every controls used in an application must be preceded by Brail (for belgium rail).

That's why i'm asking :)

darioquintana said...

I was thinking very seriously on the integration of NHV with some framework of js, so really I would like to see that integration with jQuery. I'm waiting for that sample :)

Best regards

André Carlucci said...

Great post, keep the good work :)

Btw, would you be so nice to share your visual studio theme? I found it so cool!

Thanks in advance

Torkel Ödegaard said...

For my visual studio theme:

André Carlucci said...

thanks a lot :)

w3c said...

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

w3c said...

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

Cindy Dy said...

It's enjoyable to learn more and more from your blog. Thanks for sharing.