2

I'm attempting to create my own client side validation attribute that would validate the property of a form on submit. I have been referencing the following Microsoft document: https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-2.1#custom-validation.

I am unsure on how to add the validation rule to jQuery's validator object. This is how far I have gotten:

My ValidationAttribute is as follows

public class CannotEqualValue : ValidationAttribute, IClientModelValidator
{
    private readonly string _value;

    public CannotEqualValue(string value)
    {
        _value = value;
    }

    public void AddValidation(ClientModelValidationContext context)
    {
        if (context == null)
            throw new ArgumentNullException(nameof(context));

        MergeAttribute(context.Attributes, "data-val", "true");
        MergeAttribute(
            context.Attributes, "data-val-cannotbevalue", GetErrorMessage()); //???
        MergeAttribute(
            context.Attributes, "data-val-cannotbevalue-value", _value);      //???
    }

    protected override ValidationResult IsValid(
        object value, 
        ValidationContext validationContext)
    {
        var category = (Category) validationContext.ObjectInstance;

        if (category.Name == _value)
            return new ValidationResult(GetErrorMessage());

        return ValidationResult.Success;
    }

    private bool MergeAttribute(
        IDictionary<string, string> attributes, 
        string key, 
        string value)
    {
        if (attributes.ContainsKey(key)) return false;

        attributes.Add(key, value);
        return true;
    }

    private string GetErrorMessage()
    {
        return $"Name cannot be {_value}.";
    }
}

The ValidationAttribute is used in a model like so

public class Category
{
    [Key]
    public int Id { get; set; }

    [Required(ErrorMessage = "Name is required and must not be empty.")]
    [StringLength(200, ErrorMessage = "Name must not exceed 200 characters.")]
    [CannotEqualValue("Red")]
    public string Name { get; set; }
}

I am referencing both jQuery validation and unobtrusive in my page.

I am unsure on how to add the rule to jQuery's validator object:

$.validator.addMethod("cannotbevalue",
    function(value, element, parameters) {
        //???
    });

$.validator.unobtrusive.adapters.add("cannotbevalue",
    [],
    function(options) {
        //???
    });

1 Answer 1

2

Your MergeAttribute(..) lines of code in the AddValidation() method are correct and will add the data-val-* attributes for client side validation.

Your scripts need to be

$.validator.addMethod("cannotbevalue", function(value, element, params) {
    if ($(element).val() == params.targetvalue) {
        return false;
    }
    return true;
});

$.validator.unobtrusive.adapters.add('cannotbevalue', ['value'], function(options) {
    options.rules['cannotbevalue'] = { targetvalue: options.params.value };
    options.messages['cannotbevalue'] = options.message;
});
Sign up to request clarification or add additional context in comments.

10 Comments

The data-val attributes are added, however the validation still isn't firing: <input class="form-control frmInput" id="categoryName" placeholder="Name" type="text" data-val="true" data-val-cannotbevalue="Name cannot be Red." data-val-cannotbevalue-value="Red" data-val-length="Name should not exceed 200 characters." data-val-length-max="200" data-val-required="Name is required and must not be empty." name="Category.Name" value="">
And the scripts work just fine (I have tested it - if you enter "Red" and tab out a validation message will be displayed in your @Html.ValidationMessageFor(m => m.Category.Name) placeholder (or the tag helper if your using that)
Why change the id attribute (although its irrelevant). Use you browser tools to debug the scripts. I assume you have included both jquery.validate.js and juuery.validate.unobtrusive.js and the scripts are in the correct order?
And here is a DotNetFiddle to prove it. Enter "Red" in the textbox and tab out - the validation message is displayed
Its the way jquery.validate.unobtrusive.js` works when parsing the html to read the data-val-* attributes and add the rules to the $.validator (if you put it in $(document).ready() its too late and the rule is not added)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.