It is very easy to implement new validations. We will demonstrate it through the looking at the implementation of the RegexValidation and MatchesAttribute classes.
Implement the pure validation
Create a class and derive from
ValidationBase. Now implement your validation logic:
public class RegexValidation : ValidationBase
{
private readonly Regex _regex;
public RegexValidation (string pattern, RegexOptions options = RegexOptions.None)
{
_regex = new Regex (pattern, options);
}
// actual implementation of IValidation.Validate
public override void Validate (object value, string paramName,
IValidationContext context)
{
if (value is string)
Validate ((string) value, paramName);
else
// throw an exception if the type is not as expected
ThrowExceptionForIncompatibleType (paramName, typeof (string));
}
private void Validate (string value, string paramName)
{
if (!_regex.IsMatch (value))
{
// throw an exception for invalid values
var message = string.Format ("Value must match pattern '{0}'", _regex);
throw new ValidationException (message, paramName);
}
}
}
You can not only access the appropriate value, but also the context of validation:
// MethodInfo, ConstructorInfo, or PropertyInfo
MethodBase Method { get; }
// object whose method call is being validated
object Instance { get; }
// arguments passed to the method
object[] Arguments { get; }
// return value of the method
object ReturnValue { get; }
Implement the validation attribute
Create a class and derive from
ValidationAttributeBase. Now pass the validation object to the base constructor:
public class MatchesAttribute : ValidationAttributeBase
{
public MatchesAttribute (string pattern, RegexOptions options = RegexOptions.None)
: base(new RegexValidation(pattern, options))
{
}
}