The ASP.Net MVC framework comes with built-in model validation using the Data Annotation validators. Unfortunately, the Data Annotations aren’t as robust as other validation libraries, such as the Castle Validators.
Implementing a custom model validator (for server-side validation — client-side validation requires more than is covered in this post), you need to write an implementation of the ModelValidator and ModelValidatorProvider classes that support the Castle Validators.
An example of how to do this follows. Though it hasn’t been fully tested, it worked for a handful of situations I experimented with. Use this as a starting point for your own server-side model validator implementation.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Castle.Components.Validator;
namespace ComputerSims.Baseball.Web.Infrastructure
{
///
///
public class CastleModelValidator : ModelValidator
{
private readonly IValidatorRegistry _registry;
///
///
/// The metadata.
/// The controller context.
/// The validator.
public CastleModelValidator(ModelMetadata metadata, ControllerContext controllerContext, IValidatorRegistry registry)
: base(metadata, controllerContext)
{
_registry = registry;
}
///
///
/// The container.
///
public override IEnumerable
{
if (Metadata.Model != null && Metadata.PropertyName == null)
{
IValidatorRunner runner = new ValidatorRunner(_registry);
if (!runner.IsValid(Metadata.Model))
{
ErrorSummary errors = runner.GetErrorSummary(Metadata.Model);
foreach (string property in errors.InvalidProperties)
{
yield return new ModelValidationResult()
{
MemberName = property,
Message = errors.GetErrorsForProperty(property)[0]
};
}
}
}
yield break;
}
}
///
///
public class CastleModelValidatorProvider : ModelValidatorProvider
{
private IValidatorRegistry _registry;
///
///
/// The validator.
public CastleModelValidatorProvider(IValidatorRegistry registry)
{
Guard.NotNull(registry, “registry”);
_registry = registry;
}
///
///
/// The metadata.
/// The context.
///
public override IEnumerable
{
if (metadata.Model != null && metadata.PropertyName == null)
{
yield return new CastleModelValidator(metadata, context, _registry);
}
}
}
}
I hope this helps those using the Castle Validators with the ASP.Net MVC framework!