为什么验证器会收到我的旧错误消息而不是新的错误消息?

时间:2014-05-29 14:19:57

标签: c# javascript jquery asp.net-mvc validation

我正在使用MVC5,其中包含一个包含以下字段的表单:

StudentType - Radio button
GradId - dropdown
HSYearofGradId - dropdown
CollegeStatusId - dropdown

根据这些字段,我想根据他们选择的内容在HSYearofGradId上应用验证规则。例如,如果他们选择StudentType A ,他们只会看到GradId,并且只有当他们选择GradId中的第三项时,他们才会看到HSYearofGradId }。同样,如果他们选择StudentType B ,他们会同时看到GradIdHSYearofGradId。这里的关键是StudentType A B 不同,因此错误消息应显示不同的值。

我有以下错误消息:You must select an option for your year of {0} in order to proceed."我想用客户端的值替换{0}。

在单步执行JavaScript之后,我注意到我的字符串最初被替换,但后来被我设置的原始错误覆盖:You must select an option for your year of {0} in order to proceed. I noticed this in one validator's internals: $。validator.format(message.replace(theregex, " {$ 1}"),rule.parameters);`将{0}更改为[object object]。

我使用以下问题作为参考: How to change MVC custom client-side validation error message at runtime using jQuery?

所以,我使用了MVC不引人注目的客户端验证功能。我创建了一个自定义验证属性,实现了IClientValidatable接口。 GetClientValidationRules方法如下所示:

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var modelClientValidationRule = new ModelClientValidationRule
        {
            ValidationType = "requiredif",
            ErrorMessage = ErrorMessage
        };

        // rule.ValidationParameters["condition"] = "#" + Condition; // CSS Selector (won't work if applied to nested properties on a viewmodel)

        // Attached to field
        modelClientValidationRule.ValidationParameters.Add("property", Property);
        modelClientValidationRule.ValidationParameters.Add("condition", Condition);
        modelClientValidationRule.ValidationParameters.Add("minimum", Minimum);
        modelClientValidationRule.ValidationParameters.Add("errormessage", ErrorMessage);

        yield return modelClientValidationRule;
    }

此验证属性应用于以下属性,如下所示:

        [Display(Name = "College Student Status")]
        [Integer(ErrorMessage = "You must select an option for College Student Status in order to proceed.")]
        [RequiredIf("StudentType", "college", 1, ErrorMessage = "You must select an option for College Student Status in order to proceed.")]
        public Nullable<int> CollegeStatusId { get; set; }

        [Display(Name = "When will you graduate?")]
        [Integer(ErrorMessage = "You must select an option for when will you graduate in order to proceed.")]
        [RequiredIf("StudentType", "high school", 1, ErrorMessage = "You must select an option for when will you graduate in order to proceed.")]
        public Nullable<int> GradId { get; set; }

        [Display(Name = "HS Year")]
        public string HighSchoolYear { get; set; }

        // Choosing 3rd option for gradId
        [Display(Name = "In which year did you graduate?")]
        [Integer(ErrorMessage = "You must select an option for your year of graduation to proceed.")]
        [RequiredIf("StudentType", "3", 1, ErrorMessage = "You must select an option for your year of {0} in order to proceed.")]
        public Nullable<int> HSYearofGradId { get; set; }

我在.js文件中有客户端验证函数,如下所示:

jQuery.validator.addMethod('requiredif', function (value, element, params) {
var validator = this;
var conditionIsMet = false;
var propertyId = $(element).attr('data-val-requiredif-property');
var condition = $(element).attr('data-val-requiredif-condition');
var minimum = $(element).attr('data-val-requiredif-minimum');
var errorMessage = $(element).attr('data-val-requiredif-errormessage');
var errors = {};
var radioValue = $("input[name='" + propertyId + "']:checked").val();

if (propertyId === "StudentType") {

    // i.e. high school
    if (radioValue === condition) {
        conditionIsMet = true;
    }
}
else if (propertyId === "HighSchoolLocal") {
    // what if not dropdown
    if (value === "") {

        // check if we are in no mode.
        if (radioValue === condition) {
            conditionIsMet = false;
        } else {

            if ($('#LocalBoroughId').is(':disabled')) {
                conditionIsMet = false;
            } else {
               conditionIsMet = true; 
            }
        }
    }
}

//TODO: hardcoded value
if (element.id === "HSYearofGradId") {
    if (parseInt($(element).val()) < parseInt(minimum)) {
        var gradType;

        if (radioValue === 'college') {

            // TODO: error message is still wrong
            gradType = "High School graduation";
        } else {
            gradType = "graduation";
        }

        errors[element.name] = $.validator.format(errorMessage, gradType);

        $.validator.messages.requiredif = $.validator.format(errorMessage, gradType);

        validator.showErrors(errors);

        conditionIsMet = false;
    } else {
        conditionIsMet = true;
    }

} else if (value) {
    if (parseInt(value) < parseInt(minimum)) {

        errors[element.name] = errorMessage;

        validator.showErrors(errors);
        conditionIsMet = false;
    } else {
        conditionIsMet = true;
    }
}

return conditionIsMet; });

这是适配器:

jQuery.validator.unobtrusive.adapters.add('requiredif', {}, function (options) {
options.rules['requiredif'] = options.params;

if (options.message != null) {
    options.messages['requiredif'] = options.message;
}});

修改 我想我发现了这个问题。 jquery.validate.js中有一些方法可以获取给定元素名称和验证方法的自定义消息。所有参数都传递给以下方法。我注意到列表中的第一个错误被传回。此外,第一个错误恰好是实体上设置的原始错误。

findDefined: function() {
        for (var i = 0; i < arguments.length; i++) {
            if ( arguments[i] !== undefined ) {
                return arguments[i];
            }
        }
  • 0:&#34;您必须为您的高中毕业年份选择一个选项 为了继续。&#34;
  • 1:undefined
  • 2:undefined
  • 3:&#34;您必须为您的高中毕业年份选择一个选项才能继续。&#34;
  • 4:&#34; 警告:没有为HSYearofGradId定义消息&#34;

临时解决方案:

我不知道这是不是最好的方法,但它确实有效。

this.settings.messages["FIELDNAME"]["VALIDATION_NAME"] = "NEW MESSAGE"

就我而言,我做了以下事情:

errors[element.name] = $.validator.format(errorMessage, gradType);

$.validator.messages.requiredif = $.validator.format(errorMessage, gradType);

this.settings.messages["HSYearofGradId"]["requiredif"] = $.validator.messages.requiredif;

0 个答案:

没有答案