Reputation: 30922
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?
Upvotes: 45
Views: 31997
Reputation: 10889
The IClientModelValidator
is in fact the right interface. I've made a contrived sample implementation below.
[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;
}
}
public class ContactModel
{
[CannotBeRed(ErrorMessage = "Red is not allowed!")]
public string Message { get; set; }
}
@model WebApplication.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>
}
Upvotes: 65