ASP.NET MVC 3 client-side validation with parameters

32,519

You could use the ValidationParameters property to add custom parameters to the rule:

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    var rule = new ModelClientValidationRule
    {
        ErrorMessage = this.ErrorMessage,
        ValidationType = "futuredate",
    };
    rule.ValidationParameters.Add("param1", "value1");
    rule.ValidationParameters.Add("param2", "value2");
    yield return rule;
}

which could be used in the adapter:

jQuery.validator.unobtrusive.adapters.add(
    'futuredate', 
    [ 'param1', 'param2' ],
    function (options) {
        var param1 = options.params.param1; // shall equal 'value1'
        var param2 = options.params.param2; // shall equal 'value2'
        // TODO: use those custom parameters to define the client rules
    }
);

UPDATE:

As requested in the comments section here's how you could pass those parameters to the custom validator rule function:

jQuery.validator.unobtrusive.adapters.add(
    'futuredate', 
    [ 'param1', 'param2' ],
    function (options) {
        // simply pass the options.params here
        options.rules['greaterThan'] = options.params;
        options.messages['greaterThan'] = options.message;
    }
);

jQuery.validator.addMethod('greaterThan', function (value, element, params) {
    // params here will equal { param1: 'value1', param2: 'value2' }
    return ...
}, '');
Share:
32,519
ricardo
Author by

ricardo

Updated on July 09, 2022

Comments

  • ricardo
    ricardo almost 2 years

    Following on from this post Perform client side validation for custom attribute

    I am trying to get my head around how to do this, passing additional parameters to the client-side script

    As I understand it so far to implement custom validation with MVC 3 the following is required

    Create a custom validation attribute

    Based on ValidationAttribute and implementing IClientValidatable. I have also see some examples deriving from ModelValidator, which seems to implement the functionality of both ValidationAttribute and IClientValidatable. So this is my first point of confusion as to what the diffirences are or whether ModelValidator was used in MVC 2 but is now deprecated or what ?

    An instance of ModelClientValidationRule must be returned from GetClientValidationRules() to specify details such as the error message, ValidationType (which I understand to be the name of the Javascript function that will perform the client-side validation) and any additional custom parameters that the attribute may have, and that need to be passed to the Javascript validation.

    I assume that the runtime (not sure which part of it) then use the ModelClientValidationRule to generate html attribute in the tag elements as follows:

    data-val="true"  (to indicate that the element requires validation)
    data-val-[ValidationType]=[ErrorMessage]
    data-val-[ValidationType].[ValidationParameters(n).Key]=[ValidationParameters(n).Value]
    

    Implement the client-side validation logic

    A Javascript function must be created and added to jQuery.validators with jQuery.validators.addmethod() so that JQuery is aware of it when it need to be executed. Something like:

    jQuery.validator.addMethod(
        'greaterThan', 
        function (value, element, params) {
            /.../
           return /* true or false   */ ; 
        },
        ''
    ); 
    

    My question here is whether the signature 'function (value, element, params)' is standard for methods that will handle validation and I assume it will be called by some jQuery functionality at the appropriate time such as before a form is submitted or when an element looses fuces or on keyUp events. I just don't undertand how you can controll this i.e. choose which event is appropriete for yout custom validation.

    Implement an unobtrusive adapter

    This translates unobtrusive attributes to; something I am not very clear on, but assume it to be a jQuery Rule, but I am not clear on how those work. Something like

    jQuery.validator.unobtrusive.adapters.add(
        'futuredate', 
        { },
        function (options) {
            options.rules['greaterThan'] = true;
            options.messages['greaterThan'] = options.message;
        }
    ); 
    

    My question here is about 'function (options)'. Is this the function that will be called before 'function (value, element, params)' and is responsible for extracting the unobtrusive tags into a data structure that can be understood by jQuery.Validation. From the code example it seems to me that options is an object that contains both, the attribute values from the tag (such as options.message) and the jQuery relevant properties it must map to (such as options.messages['ClientSideValidationFunctionName']. If so how are custom parameters retrieved and mapped.

    I hope I have not added any additional confusion.

  • ricardo
    ricardo over 13 years
    ok great. Could you also please show how I would reference those params in the script that would perform the validation. This is where I am now stuck. I understand the method signature for the validation is function (value, element, params), but am not sure how param1 and param2 are passed to it
  • ricardo
    ricardo over 13 years
    P.S. I have register the validationmethod with jQuery.validator.addMethod('validationtype', function (value, element, params) { /* ...*/ },'');
  • Darin Dimitrov
    Darin Dimitrov over 13 years
    @ricardo, does this answer your question?
  • ricardo
    ricardo over 13 years
    Apologies for being a bit dence. Would you mind showing me some code accessing those like just an alert please.
  • Darin Dimitrov
    Darin Dimitrov over 13 years
    @ricardo, you could alert(params.param1); or alert(params.param2);
  • ricardo
    ricardo over 13 years
    AaaaHH Yes finally. I was trying that but had not assigned options.rules['greaterThan'] = options.params. Thanks your are a star. It is really hard to find any complete exampels. I think the naming options.rules to assign the parameters is not very intuative . 'rules; was indicative to me of having to provide the name of the function that would enforce the rule, but I now understand that it server to provide the variables required. Thanks again
  • ricardo
    ricardo over 13 years
    Actually could you possibly also shed some light on some of these other related question in my post ...
  • ricardo
    ricardo over 13 years
    1. What is the diffirence between deriving from ValidationAttribute end implementing IClientValidatable or deriving from ModelValidator or DataAnnotatiopnModelValidator
  • ricardo
    ricardo over 13 years
    2. Is 'function (value, element, params)' the standard and jQuery validation function or doe sit belong to Microsoft's unobtrusive validation
  • Darin Dimitrov
    Darin Dimitrov over 13 years
    @ricardo, concerning your first question, ModelValidator allows you to achieve the same thing as with IClientValidatable as it exposes the GetClientValidationRules method. As far as your second question is concerned, that's jquery validation.
  • ricardo
    ricardo over 13 years
    So there is no compelling reason to use DataAnnotationModelValidator one over ValidationAttribute with IClientValidatable. ?
  • Darin Dimitrov
    Darin Dimitrov over 13 years
    @ricardo, ValidationAttribute acts on a single property of your model whereas a ModelValidator acts on the entire model.
  • ricardo
    ricardo over 13 years
    That was what I thought to, but having read this several posts I have noted that ValidateAttribute now also as an IsValid(object value, ValidationContext context) which as I understand it give access to the whole model. So I am wondering if there is any other reason to derive from ModelValidator
  • Paul Hiles
    Paul Hiles over 13 years
    The ModelValidator approach is from MVC2 and in my opinion, should not be used going forward on an MVC3 project. The MVC3 ValidationAttribute/IClientValidatable approach is much cleaner and does not involve modifying the global.asax to register the adapter.
  • kdawg
    kdawg over 13 years
    holy crap, this line of comments is exactly what i needed. i've been working with an mvc 2 site that i updated to mvc 3. it has a custom "RequiredIf" ValidationAttribute that uses DataAnnotationsModelValidator and all that stuff described here: haacked.com/archive/2009/11/19/…. I was getting so confused by the old way and these new mvc3 ways of doing it. apparently they achieve the same thing. thanks for the documentation (and heads up) on this, microsoft! sigh Thanks Darin, ricardo, and The Flower Guy!
  • kdawg
    kdawg over 13 years
    Of course, I'm still not totally set on this stuff. If someone were to post a blog entry or something describing what's new in mvc 3 and what it replaces from mvc 2 regarding emitting client-side validation from custom DataAnnotations, that'd be the bees knees! =D
  • Softlion
    Softlion about 13 years
    In fact DataAnnotationsModelValidator in MVC3 is still useful if the attribute is not your attribute, or if it is in another assembly which does not reference the Mvc assembly.
  • Glory Raj
    Glory Raj almost 11 years
    @DarinDimitrov would you pls tell what is meant by this one ['greaterThan'] .. is this is the method name like this one ...'futuredate' or any other thing...
  • Alexandr
    Alexandr over 8 years
    How can I test such Validator?