...

/

Designing Custom Validation Attributes

Designing Custom Validation Attributes

In this lesson, we will learn code a custom validation attribute that will perform both server-side and client-side validation.

A custom validation attribute can be implemented by inheriting from the ValidationAttribute class. Server-side validation code is provided by overriding the methods that perform validation and error message formatting.

Client-side validation requires that our attribute implements the IClientModelValidator interface whose unique AddValidation method specifies the data- attributes to add to the input field. The actual client-side validation code must be provided through a JavaScript validator which is connected to the parser that processes all data- attributes through a JavaScript adapter.

We will describe all the above steps while implementing an example custom validation attribute: the ExtensionAttribute.

The ExtensionAttribute

As an example, we will define an attribute that checks the extension of a Web Address. It is useful when combined with the UrlAttribute to force the user to insert the address of a pdf, or of a supported image type. The basic idea is to pass it a string with all comma-separated allowed extensions. Something like .jpg,.jpeg, or .png. The usage should be similar to the example below:

Press + to interact
[Display(Name="URL of picture"), Url, Extension(".jpg,.jpeg,.png")]
public string WebPicture { get; set; }

The combined usage of both UrlAttribute and ExtensionAttribute forces the user to insert the Web Address of an image.

Server-side validation

Custom attributes can be inserted in a folder called Validation that is placed in the application root. There, we can add an ExtensionAttribute class that inherits from ValidationAttribute:

Press + to interact
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace MvcProject.ViewModels
{
public class ExtensionAttribute: ValidationAttribute, IClientModelValidator
{
private const string defaultMessage = "{0} is not a a supported image addrees";
private string extensions;
public ExtensionAttribute(string extensions)
{
this.extensions = extensions;
}
private string extensions;
public ExtensionAttribute(string extensions)
{
this.extensions = extensions;
}
public override bool IsValid(object value)
{
...
}
}
}

The default namespace name has been changed to match the namespace of all ViewModels, so we don’t need any using to use it with our ViewModels. ...