A few weeks ago I introduced a new project o Castle’s trunk: Castle.Components.Validator. This was supposed to go to the Castle.Core, but to prevent the third world war from starting on castle mailing list, I decided to go with a separated assembly. This project has no dependencies, and can be used on a variety of projects and environments. I’ll try to explain the basics here and see what happens.
What itchy it scratches
The project’s goal was to create a thin, lightweight and flexible validation framework. Validation rules are – conceptually – attached to Types. The standard way is to use attributes, but they are not obligatory.
How does it work
The main entity is the ValidatorRunner, and it requires an IValidatorRegistry instance. The registry keeps the set of validators associated with a type and its properties. Out of box there’s a CachedValidationRegistry implementation which uses reflection. If you’re a xml fanatic, you can create a IValidatorRegistry implementation that reads from a xml file.
For performance reasons you should only have a single IValidatorRegistry instance. The ValidatorRunner should be created per activity, as it is stateful.
Using it
To use the Validator you just need to instantiate the runner and use one of the IsValid overload:
ValidatorRunner runner = new ValidatorRunner(new CachedValidationRegistry());
if (runner.IsValid(customer))
{
// do something with customer
}
else
{
MessageBox.Show("Whoops!");
}
After invoking the IsValid you can use the GetErrorSummary(instance) to grab a detailed list of what went wrong.
The validators
A validator is just an ordinary class that implements the IValidator attribute. The important method is the IsValid. The code for NonEmptyValidator follows:
public class NonEmptyValidator : AbstractValidator
{
public override bool IsValid(object instance, object fieldValue)
{
return fieldValue != null && fieldValue.ToString().Length != 0;
}
..
}
The attributes
If you create a new validator, you’d usually use an attribute to associate it with a property. The attribute is required to implement IValidatorBuilder. The implementation for ValidateNonEmptyAttribute follows:
public class ValidateNonEmptyAttribute : AbstractValidationAttribute
{
public ValidateNonEmptyAttribute()
{
}
public override IValidator Build()
{
IValidator validator = new NonEmptyValidator();
ConfigureValidatorMessage(validator);
return validator;
}
}
i18n support
The default error messages are available in english, portuguese and dutch, using satellite assemblies. I considered an approach to have custom error messages and yet “localizable” ones, but gave up after 20 minutes. The best I could think of was using a special string that indicates an assembly should be loaded. Something like
public class Customer
{
[ValidateNonEmpty(LocalizableMessage='name_is_required')]
public string Name
{
..
}
}
Javascript integration
The validator can declare that they support web validation. That means that a validator can configure a js library to perform the same validation it is supposed to perform. This is done using the IWebValidationGenerator, which exposes operation that most of the js validation libraries implement.
For example, here is a code snippet from the NonEmptyValidator:
public override bool SupportsWebValidation
{
get { return true; }
}
public override void ApplyWebValidation(WebValidationConfiguration config, InputElementType inputType,
IWebValidationGenerator generator, IDictionary attributes)
{
generator.SetAsRequired(BuildErrorMessage());
}
It is up to the implementation of IWebValidationGenerator to attach the html to the element attributes. MonoRail has two implementations: for fValidate and for the Prototype Validation.
… and more!
Some validations may make sense for a situation, and be totally unnecessary in other. That’s why you can associate phases with validations:
[ValidateSameAs("Password", RunWhen=RunWhen.Insert)]
public string Confirmation
{
get { return confirmation; }
set { confirmation = value; }
}
The possible phases are: everytime, insert, update and custom.
When you use the runner, you can tell it to restrict the validation to a specific phase:
bool isValid = runner.IsValid(customer, RunWhen.Custom);
You can also define an execution order:
[ValidateNonEmpty(ExecutionOrder=1)]
[ValidateLength(3, 12, "Invalid password length", ExecutionOrder=2)]
public string Password
{
get { return pwd; }
set { pwd = value; }
}
A friendly name for a property may also be handy:
[ValidateNonEmpty(FriendlyName="CoResponsible user")]
public string CoResponsibleUserName
{
get { return secondUser; }
set { secondUser = value; }
}
The class diagram
If you want to give it a try, grab Castle’s source, or browse the source code.
Have fun!

February 4th, 2007 at 10:07 am
I translate the messages also in italian.
How can I send it to you?
February 4th, 2007 at 10:44 am
You can send a .patch file to the list, or through jira. See http://support.castleproject.org
February 4th, 2007 at 7:04 pm
Hi,
Me and a friend of mine are currently working on Contracts ( http://www.codeplex.com/contracts ) which uses DynamicProxy to automagically check the validators when a property or method is called.
Is there a possibility to include something like this in Castle ?
February 4th, 2007 at 8:20 pm
I personally don’t like this approach, but if there’s a community claim to have something like that added to Castle, I’d definitely consider it.
February 9th, 2007 at 7:14 am
It seems like I cannot find the LocalizableMessage property?
February 9th, 2007 at 10:20 am
Because there isn’t one. I couldn’t find a way to fully handle i18n yet, and I’m open for suggestions.
February 10th, 2007 at 2:08 pm
See if this looks ok for you:
[Resource(ResourceName='MyResourceLibName', AssemblyName='AssemblyName')]
public class MyClass
{
[FieldResource(FieldNameResourceKey='ResourceKey')]
[Validator(MessageResourceKey='ResourceKey')]
public int MyField
{
}
}
then in the message resource string:
en-US: $fieldName is required.
zh-tw: Ni Bi Shu Ten Shan $fieldName.
so the field name are isolated from the message, makes localization much easier (you dont have to create 20 full message for field required, instead just create field label for each field and then the message template)
I did something similar in fValidateLang indeed, I think that works.
February 10th, 2007 at 8:42 pm
It works, but it’s too verbose. I’m considering approaches…
February 13th, 2007 at 1:20 am
I suggest you put up a topic in devel group for everyone to discuss? Anyhow I think its quite important (at least for me) so I would like to have a workable approach soon whenever soonest possible.
February 13th, 2007 at 8:40 am
goodwill, you can start this topic on the devel list. I’d appreciate your use-cases and suggestions for it.
January 5th, 2008 at 8:08 am
if someone have been doing anything about i18n of validation, please, inform tell me. I chose to create a project with MonoRail and AR in language different then english, so soon I will need to supply site with localized error messages and I cant use the technique above, if it is not i18nable.
January 5th, 2008 at 5:17 pm
It already has lots of translations: http://svn.castleproject.org:8080/svn/castle/trunk/Components/Validator/Castle.Components.Validator/
April 13th, 2008 at 9:55 pm
[...] to add validation to a web application I am building using MonoRail. A bit of research turned up a brilliant component created by Hammett that greatly simplifies adding client and server side validation in one [...]
September 9th, 2008 at 4:07 pm
[...] Hamilton Verissimo – link [...]
January 19th, 2009 at 9:46 am
[...] can be found in the Castle.Components.Validator namespace under “Attributes” and more information here. (I hadn’t used it till today). The best thing to do would be to download Emad’s sample [...]
February 3rd, 2009 at 5:25 pm
[...] series, I showed how you can perform basic server-side validation on your model with help of the Castle Validator component. To summarize this post: the controller validates an object that is decorated with validation [...]
February 3rd, 2009 at 5:28 pm
[...] Cuyahoga, we’re using the Castle Validator component to perform basic validation, mostly because we’re already using other components from the [...]
February 3rd, 2009 at 5:31 pm
[...] multi-part post about validation with Castle validators and ASP.NET [...]
March 4th, 2009 at 4:44 am
Would you consider supporting System.ComponentModel.DataAnnotations .Metadatatype attribute? It allows you to define the validation attributes on a class other than the entity class. Would be of great value for Linq to SQL projects as entity classes are auto generated. Or is it possible to subclass on of the classes of Castle Validator to allow getting custom attributes from a different source?
Example:
[Metadatatype(typeof(PersonMetaData))]
public class Person
{
public string Name {get;set;}
}
public class PersonMetaData
{
[ValidateLength(1,40)]
public string Name {get;set;}
}
March 4th, 2009 at 1:34 pm
@rekna you should bring this suggestion to the castle devel mailing list. thanks
March 5th, 2009 at 8:28 pm
I manage to get translated messages using this code:
if (model == null) return;
ResourceManager mgr = new ResourceManager(“Castle.Components.Validator.Messages”, Assembly.GetAssembly(typeof(Castle.Components.Validator.CachedValidationRegistry)));
var runner = new ValidatorRunner(new CachedValidationRegistry(mgr));
if (runner.IsValid(model) || !runner.HasErrors(model)) return;
var summary = runner.GetErrorSummary(model);
throw new RuleViolationException(summary);
The errors get translated correctly, but in the validation summary, the names of the properties are not mentioned.. I think it would be better to get ‘XXX’ is required instead of ‘This is a required field’?
March 5th, 2009 at 8:30 pm
Added CachedMetadataValidationRegistry (for support of MetadataType) to support.castle.org