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?
Implementing IClientModelValidator interface This method sets certain client side custom data attributes or data-* attributes that are used by the validation system.
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.
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.
[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; } }
[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)); } }
public class ContactModel { [CannotBeRed(ErrorMessage = "Red is not allowed!")] public string Message { get; set; } }
@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> }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With