Defining Custom Client Validation Rules in Core MVC

Editor’s note: The following post was written by Visual Studio and Development Technologies MVP Francesco Abbruzzese as part of our Technical Tuesday series with support from his technical editor Michele Aponte, who is an MVP in the same category. core MVC is not only a multi-platform porting of classic MVC. But it’s a complete rewrite and reengineering of the product, meant to increase performance and modularity. Several areas that evolved incrementally from MVC 1 to MVC 5 have been cleaned up and simplified into a homogeneous design, which is founded on a few fundamental concepts –  like Dependency Injection, Middleware Pipeline, and the new options framework. In this article, I’ll focus on client side validation and on how the developer may define his or her custom client validation rules.

The way MVC handles client side validation has relied on unobtrusive validation since MVc 3. All client validation rules for each input field are extracted from various sources, including validation attributes, and the type of property to be rendered and encoded in the content of Html5 data.

On the client side, input fields are parsed to extract these rules, with the help of rule specific JavaScript adapters that take care of instantiating adequate jQuery Validation Plugin validation rules. While in Core MVc the key concepts and all JavaScript handling of client validation remained the same, its server side handling changed substantially to take advantage of the new Dependency Injection and Option frameworks. In this article, I will show in detail two procedures for providing YouTube URL client validation.

Where do client validation rules come from?

Client validation rules are rendered by implementing the IClientModelValidator interface. This exposes the single method AddValidation to create all Html5 data – attributes needed by the client validation rule. IClientModelValidator implementations are created by providers, which extract the validation rules from various sources. I will analyze two important sources: validation attributes, and property metadata.

We need an core application:


Let’s call it CustomValidationdemo. Then select WebApplication and Individual User Accounts for the authentication.

Client validation with validation attributes

In order to test validation attributes, we need a YouTubeAttribute:


Let’s add it to a newly created Validation folder. Since this article is about client validation, I’ve written no server side validation logic.

Now we need an IClientModelValidator implementation to associate with this attribute. Since validation, attributes are first class citizens. In core we have the AttributeAdapterBase<T> class to inherit from:


It is enough to merge the data- attributes into the dictionary contained in the context object passed to the AddValidation method. “data-val=true” selects all input fields that need some client validation, so it is rendered once for each input field, having at least once validation rule. The second data-val-* attribute specifies the name of the validation rule (in our case “youtube”) and provides the error message.

We don’t need more data- attributes since our validation rule has no parameters. Validation rules with parameters (as for instance the one associated with the RangeAttribute) add further attributes named like data-val-rulename-par1, data-val-rulename-par2, etc., that define both the parameter names and their values.

In the GetErrorMessage method, we extract the display name of the property to render in the input field from the property metadata, and pass it to the inner GetErrorMessage method inherited from AttributeAdapterBase<T>. This, in turn,  extracts the error message contained in our YouTubeAttribute (“{0} is not a valid YouTube Url”), localizes it with stringLocalizer (see, and finally uses it as a format string whose unique “hole” is filled with the property display name.

A unique provider scans all ValidationAttributes and for each of them instantiates the appropriate IClientModelValidator. It implements the IValidationAttributeAdapterProvider interface. We need to substitute its default implementation with a custom provider that processes also our YouTubeAttribute.


Our implementation checks for the YouTubeAttribute and then calls the default implementation. Since the IValidationAttributeAdapterProvider is injected, we may install our provider easily by declaring it in the ConfigureServices section of the web site Startup class.


That’s all! We have completed the configuration on the server side.

Defining client validation rules on the client side

On the JavaScript side, we need a function that actually performs the validation and an adapter that, once invoked by the unobtrusive parser, adds this function to the validation list for the input field being processed.


addMethod defines our new validation rule called “youtube”. Our function receives both the value typed by the user and the input field. Our rule has no parameters, but in general, params contains rule parameters. Value is trimmed and then matched with a regular expression. We just check that the match starts at the beginning of the URL typed by the user, but we don’t pretend that the match covers the whole URL, thus allowing for extra query string parameters. Instead, we pretend match[1] has a value, since it represents the group containing the YouTube video Id that for sure we need on the server side to play somehow the video.

Since our rule has no parameter (boolean rule), we may create the adapter with no further coding effort, by simply calling addBool. For more information on how to create adapters for rules with parameters, please refer to the JavaScript part of this famous Brad Wilson article:

Testing the YouTube URL validation rule

To test the rule, define this simple ViewModel.


Then open the “Home\Index.cshtml” view, delete its content and substitute it with:


Run and enjoy!

An alternative implementation based on type metadata

Client validation rules that check the right format for numbers don’t rely on validation attributes, but are inferred directly from the property type. We might do something similar with our YouTube validation rule, either by defining a YouTube data type, or by using simply the DataType attribute to declare that a string represents a YouTube URL.

This is nice, since once we decorate a property with [DataType(“YouTubeUrl”)] we can also provide adequate Display and Edit templates. For instance, a display template might simply play the video, and an Edit template might accept suggestions from one or more video sources. To carry out this plan we must implement the IClientModelValidator interface from the scratch.


This takes a little bit of extra work, since we must implement the MergeAttribute method. Moreover, we have no place to take the error message from. I wrote this in the code, but you may put it in a resource file in order to localize it. Then, we may implement the basic IClientModelValidator provider:


Our provider adds the validator to the validators list only if this list doesn’t contain another instance of the same type. This time, our validator will not substitute any other validator, but we will add it to a list of validators contained in the MVcViewOptions. Options are added/modified/configured using core options framework.


For more information on the core options framework, see To test the new implementation go to the YouTubeViewModel, comment out the YouTubeAttribute and substitute it with [DataType(“YouTubeUrl”)].


In summary, client validation rules require the implementation of the IClientModelValidator interface. If the client rule comes from a validation attribute we may inherit from AttributeAdapterBase<T>, otherwise we have to implement it from the scratch. Client rules based on validation attributes are installed by substituting the default IValidationAttributeAdapterProvider and configuring the custom implementation in the ConfigureServices section of our application. If not, we need to implement the basic IClientModelValidatorProvider interface, and add it to the ClientModelValidatorProviders list contained in the MVcViewOptions. On the JavaScript side, we must provide a function that implements the actual validation logic and an adapter that takes care of attaching properly this validation logic to the input field, when it is invoked by the unobtrusive attributes parser.

screen-shot-2016-12-22-at-8-47-12-amFrancesco Abbruzzese implements MVC applications, and has offered consultancy services since the beginning of this technology. He is the author of the famous MVC Controls Toolkit, and his company offers tools, UI controls, and services for MVC. He’s moved from decision support systems for banks and financial institutions, to the Video Games arena, and finally started his .Net adventure with the first .Net release.

Follow him on Twitter @F_Abbruzzese


Comments (1)

Skip to main content