views:

313

answers:

2

Say I have a model which has a payment date

public class PaymentModel
{
    [PaymentDateValid]
    public DateTime PaymentDate { get; set; }
}

I have created a custom validator PaymentDateValid deriving from ValidationAttribute. The validator needs to lookup from the database the latest payment date and verify that the submitted payment date is after the latest payment date.

Assume that there is some sort of Repository or Service that is used to get the latest payment date and that these are available from a container. Client side validation isn't necessary, but would be a nice to have.

What is the best way to inject these dynamic validation parameters into the validator? Or is there a better way to perform a data driven validation?

+1  A: 

To dynamically add validation attributes at runtime you need to create a custom ModelValidatorProvider:

public class MyCustomModelValidatorProvider : DataAnnotationsModelValidatorProvider
{
    protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {   
        var newAttributes = attributes;

        //or whatever other criteria you need
        if( metadata.PropertyName == "PaymentDate" )
                newAttributes.Add( new PaymentDateValidAttribute() );

        return base.GetValidators(metadata, context, newAttributes);
    }
}

Just remember to register your custom model validator provider via the global.asax.

ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new MyCustomModelValidatorProvider());
jfar
A: 

Are you sure this works?

There is no add method on IEnumerable??

newAttributes.Add( new PaymentDateValidAttribute() );