MVC model validation with Castle Validator

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

/// Implements a for the Castle Validator library.
///

public class CastleModelValidator : ModelValidator
{
private readonly IValidatorRegistry _registry;

///

/// Initializes a new instance of the class.
///

///The metadata. ///The controller context. ///The validator. public CastleModelValidator(ModelMetadata metadata, ControllerContext controllerContext, IValidatorRegistry registry)
: base(metadata, controllerContext)
{
_registry = registry;
}

///

/// Validates the object.
///

///The container. /// A list of validation results.
public override IEnumerable Validate(object container)
{
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;
}
}

///

/// Implements a for the Castle Validator library.
///

public class CastleModelValidatorProvider : ModelValidatorProvider
{
private IValidatorRegistry _registry;

///

/// Initializes a new instance of the class.
///

///The validator. public CastleModelValidatorProvider(IValidatorRegistry registry)
{
Guard.NotNull(registry, “registry”);

_registry = registry;
}

///

/// Gets a list of validators.
///

///The metadata. ///The context. /// A list of validators.
public override IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context)
{
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!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>