I'm adding a custom validation attribute to my code and it works perfectly server side. However, on client side, the method and adapter are registered but the validation function is never called.
I'm working in .NET Core 2.2 using MVC. I've removed the $(Document).Ready wrapper as suggested elsewhere and verified that all of the casing matches.
The following is an MRE
The Test Validation Attribute:
public class TestValidationAttribute : ValidationAttribute, IClientModelValidator
{
public TestValidationAttribute(string name)
{
_name = name;
}
private string _name;
protected override ValidationResult IsValid(Object value, ValidationContext validationContext)
{
return new ValidationResult($"{_name} has been validated");
}
void IClientModelValidator.AddValidation(ClientModelValidationContext context)
{
context.Attributes.Add("data-val", "true");
context.Attributes.Add("data-val-testvalidation", $"{_name} has been validated client side");
context.Attributes.Add("data-val-testvalidation-name", _name);
}
}
The Model:
public class TestModel
{
[TestValidation("Hello World!")]
[Display(Name = "Test Value")]
public string TestValue { get; set; }
}
The View:
<div class="form-group">
@using (Html.BeginForm())
{
<div class="row">
@Html.LabelFor(m => m.TestValue)
</div>
<div class="row">
@Html.EditorFor(m => m.TestValue)
</div>
<div class="row">
@Html.ValidationMessageFor(m => m.TestValue)
</div>
<div class="row">
<input type="submit" value="Submit" />
</div>
}
</div>
The Validation JS:
$(function ($) {
$.validator.addMethod('testvalidation',
function (value, element, params) {
return false;
});
$.validator.unobtrusive.adapters.add('testvalidation', ['name'],
function (options) {
options.rules['testvalidation'] = { name: options.params['name'] };
options.messages['testvalidation'] = options.messages;
});
}(jQuery));
The Generated HTML:
<div class="form-group">
<form action="/" method="post"> <div class="row">
<label for="TestValue">Test Value</label>
</div>
<div class="row">
<input class="text-box single-line" data-val="true" data-val-testvalidation="Hello World! has been validated client side" data-val-testvalidation-name="Hello World!" id="TestValue" name="TestValue" type="text" value="" />
</div>
<div class="row">
<span class="field-validation-valid" data-valmsg-for="TestValue" data-valmsg-replace="true"></span>
</div>
<div class="row">
<input type="submit" value="Submit" />
</div>
<input name="__RequestVerificationToken" type="hidden" value="" /></form></div>
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2019 - WebApplication1 - <a href="/Home/Privacy">Privacy</a>
</div>
</footer>
<script src="/lib/jquery/dist/jquery.js"></script>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
<script src="/js/testvalidation.js"></script>
<script src="/js/site.js?v=4q1jwFhaPaZgr8WAUSrux6hAuh0XDg9kPS3xIVq36I0"></script>
So, it turns out that my issue wasn't with my code but my understanding of how the validation was going to work. I was expecting it to fire on blur but it doesn't fire until submit.