Michel
Michel

Reputation: 23615

Use Client-Side Validation when custom [required] attribute is used

on this project we do not use the default dataannotation attributes from the System.ComponentModel.DataAnnotations namespace, but custom attributes are built.

So we do place a [required] attribute on a property, but it's a custom built one.

For server side validation we managed to override the validation with a custom validation provider, but we are stuck with tthe client side validation.

As i read in the docs, i see that when you use the default [required] attribute, these kind of attributes are rendered on the html elements:

data-val-lengthmax="10" data-val-length-min="3" data-val-required="The ClientName field is required."

I presume that is done by the framework, which reads the normal required attribute, and then renders the html attributes.

Can we make the framework render these attributes for us too?

Upvotes: 4

Views: 3876

Answers (2)

tpeczek
tpeczek

Reputation: 24125

In order to enable client validation in custom attribute you can implement IClientValidatable interface in your attribute:

public class requiredAttribute : ValidationAttribute, IClientValidatable
{
    ...

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        return new[] { new ModelClientValidationRule { ErrorMessage = "<Your error message>", ValidationType = "required" } };
    }
}

As an alternative you can implement validation adapter for your attribute:

public class requiredAttributeAdapter : DataAnnotationsModelValidator<requiredAttribute>
{
    public requiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
        : base(metadata, context, attribute)
    { }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        return new[] { new ModelClientValidationRule { ErrorMessage = "<Your error message>", ValidationType = "required" } };
    }
}

And register it with data annotations validation engine in your Global.asax:

protected void Application_Start()
{
    ...
    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(requiredAttribute), typeof(requiredAttributeAdapter));
}

Of course you need to make sure that you are referencing your attribute in above classes.

Upvotes: 2

Darin Dimitrov
Darin Dimitrov

Reputation: 1038730

Can we make the framework render these attributes for us too?

Yes, there are 2 possibilities:

  1. Have your custom attribute implement the IClientValidatable interface where you would implement the client validation rules.
  2. Register a custom DataAnnotationsModelValidator<TAttribute> where TAttribute will be your custom validation attribute and where you would implement your custom client side validation rules (that's the approach used by Microsoft to implement client side validation for the Required attribute and that's why if you write a custom validator attribute which derives from it you don't get client side validation). Then you need to register your custom model validator with the custom attribute using DataAnnotationsModelValidatorProvider.RegisterAdapter call.

Upvotes: 4

Related Questions