Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net Core MVC - Client-side validation for custom attribute

In previous versions of the MVC framework custom validation would be achieved through implementing IClientValidatable and the GetClientValidationRules method.

However in ASP.Net Core MVC we do not have this interface, although we do have IClientModelValidator which a defining a very similar method. The implementation of which never gets called however.

So - how do we implement client-side validation for a custom attribute in ASP.NET Core MVC?

like image 342
m.edmondson Avatar asked Apr 12 '16 07:04

m.edmondson


People also ask

Which interface is used for custom ASP .NET core client side validation?

Implementing IClientModelValidator interface This method sets certain client side custom data attributes or data-* attributes that are used by the validation system.

How can use client side validation in ASP.NET MVC?

Firstly, you just need to create an ASP.NET MVC application. To create a new ASP.NET MVC application, Open Visual Studio choose File, New, then Project. It will open a New Project window, from where you need to choose node Visual C# and then Web and from the right pane you need to choose ASP.NET Web Application.


1 Answers

The IClientModelValidator is in fact the right interface. I've made a contrived sample implementation below.

Note: There was a breaking change to the IClientModelValidator interface between RC1 and RC2. Both options are presented below - the rest of the code is the same between both versions.

Attribute (RC2 and beyond)

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public sealed class CannotBeRedAttribute : ValidationAttribute, IClientModelValidator {     public override bool IsValid(object value)     {         var message = value as string;         return message?.ToUpper() == "RED";     }      public void AddValidation(ClientModelValidationContext context)     {         MergeAttribute(context.Attributes, "data-val", "true");         var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());         MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);     }      private bool MergeAttribute(         IDictionary<string, string> attributes,         string key,         string value)     {         if (attributes.ContainsKey(key))         {             return false;         }         attributes.Add(key, value);         return true;     } } 

Attribute (RC1)

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public sealed class CannotBeRedAttribute : ValidationAttribute, IClientModelValidator {     public override bool IsValid(object value)     {         var message = value as string;         return message?.ToUpper() == "RED";     }      public IEnumerable<ModelClientValidationRule> GetClientValidationRules(         ClientModelValidationContext context)     {         yield return new ModelClientValidationRule(             "cannotbered",             FormatErrorMessage(ErrorMessage));     } } 

Model

public class ContactModel {     [CannotBeRed(ErrorMessage = "Red is not allowed!")]     public string Message { get; set; } } 

View

@model WebApplication22.Models.ContactModel  <form asp-action="Contact" method="post">     <label asp-for="Message"></label>     <input asp-for="Message" />     <span asp-validation-for="Message"></span>     <input type="submit" value="Save" /> </form>  @section scripts {     <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>     <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>     <script>         $.validator.addMethod("cannotbered",             function (value, element, parameters) {                 return value.toUpperCase() !== "RED";             });          $.validator.unobtrusive.adapters.add("cannotbered", [], function (options) {             options.rules.cannotbered = {};             options.messages["cannotbered"] = options.message;         });     </script> } 
like image 126
Will Ray Avatar answered Sep 20 '22 12:09

Will Ray