【问题标题】:ASP.NET MVC 3 Unobtrusive Jquery Validate not showing custom error messages more than onceASP.NET MVC 3 Unobtrusive Jquery Validate 不多次显示自定义错误消息
【发布时间】:2012-03-28 19:21:54
【问题描述】:

所以,我从this Microsoft provided Example 获取了一些代码,它允许我使用 jquery validate unobtrusive 库来解析从我的服务器返回的验证错误消息并将它们显示在 UI 中。他们有一个video demonstrating this。所以,这是我正在使用的一段 Javascript 代码:

   $.validator.addMethod("failure", function () { return false; });
    $.validator.unobtrusive.adapters.addBool("failure");
    $.validator.unobtrusive.revalidate = function (form, validationResult) {
        $.removeData(form[0], 'validator');
        var serverValidationErrors = [];
        for (var property in validationResult) {
            //var elementId = property.toLowerCase();
            var item = form.find('#' + property);
            if (item.length < 1) { item = form.find('#' + property.replace('.', '_')); }
            serverValidationErrors.push(item);
            item.attr('data-val-failure', validationResult[property].join(', '));
            jQuery.validator.unobtrusive.parseElement(item[0]);
        }
        form.valid();
        $.removeData(form[0], 'validator');
        $.each(serverValidationErrors, function () {
            this.removeAttr('data-val-failure');
            jQuery.validator.unobtrusive.parseElement(this[0]);
        });
    };

因此,在句柄错误函数中发布 AJAX 表单后,我会执行以下操作:

$.validator.unobtrusive.revalidate(form, { 'PhysicalAddress.CityName': ['You must select a valid city'] });

PhysicalAddress.CityName 是我的 viewmodel 属性和 html 输入字段的名称。因此,它知道将验证消息放在正确的 html 元素旁边。

这有效 1 次。然后当他们再次点击提交并且我的代码再次调用 unobtrusive.revalidate 方法时......它不起作用。它只显示一次验证消息,然后验证消息永远消失。

有人知道为什么会发生这种情况吗?..我逐步执行了重新验证方法,没有抛出任何错误,一切似乎都应该工作..但是由于某种原因,不显眼的库没有重新绑定验证错误消息。

谢谢

【问题讨论】:

    标签: asp.net-mvc-3 jquery-validate unobtrusive-validation


    【解决方案1】:

    这种行为可能取决于 jQuery 验证插件的一个已知问题:为元素动态添加新的验证规则只需一次!进一步的尝试被拒绝,因为插件认为它们是重复定义已定义规则的尝试。

    这就是为什么$.validator.unobtrusive.parse 在您添加新创建的内容时不起作用的原因(例如,当您向项目集合添加新行时)。 $.validator.unobtrusive.parse 有一个补丁,您也可以尝试将其应用于 revalidate 函数……但最好以不同的方式从头开始重写它。 revalidate 函数使用验证插件将所有验证错误放置在正确的位置,然后尝试重置验证插件的状态。但是,从表单中删除验证器对象不足以取消所有已完成的工作,因为form.data('unobtrusiveValidation') 中包含另一个对象,其中表单是包含正在验证的表单的变量...此数据不会被重新验证重置函数...并且不能重置,因为重置它们会导致取消所有客户端验证规则。

    可能这个问题在上个版本的验证插件中已经解决了,所以尝试用nuget更新到上个版本。

    如果这不能解决您的问题,我可以向您传递一个以完全不同的方式实现的类似功能(它模仿服务器在服务器端执行的操作以显示服务器端错误)。它将包含在即将发布的 Mvc Controls 工具包版本中。但是,如果你给我几天(我会很忙 2 天),我可以从那里提取它及其依赖项,以便你可以使用它。如果您有兴趣,请告诉我。

    在我承诺的代码下方。它需要一个数组,其元素是:

    {
        id:id of the element in error
        errors:array of strings errors associated to the element
    }
    

    它接受每个元素的多个错误,但只显示每个元素的第一个错误 id 与名称不同,因为 . [ ] 另一个特殊字符被替换为 _

    您可以在服务器上将 name 转换为 id

    htmlName.Replace('$', '_').Replace('.', '_').Replace('[', '_').Replace(']', '_');
    

    或在客户端使用 javascript:

    name.replace(/[\$\[\]\.]/g, '_');
    
    function remoteErrors(jForm, errors) {
        //////////
        function inner_ServerErrors(elements) {
            var ToApply = function () {
                for (var i = 0; i < elements.length; i++) {
                    var currElement = elements[i];
                    var currDom = $('#' + currElement.id);
                    if (currDom.length == 0) continue;
                    var currForm = currDom.parents('form').first();
                    if (currForm.length == 0) continue;
    
                    if (!currDom.hasClass('input-validation-error'))
                        currDom.addClass('input-validation-error');
                    var currDisplay = $(currForm).find("[data-valmsg-for='" + currElement.name + "']");
                    if (currDisplay.length > 0) {
                        currDisplay.removeClass("field-validation-valid").addClass("field-validation-error");
                        replace = $.parseJSON(currDisplay.attr("data-valmsg-replace")) !== false;
                        if (replace) {
                            currDisplay.empty();
                            $(currElement.errors[0]).appendTo(currDisplay);
                        }
                    }
                }
            };
            setTimeout(ToApply, 0);
        }
        /////////
        jForm.find('.input-validation-error').removeClass('input-validation-error');
        jForm.find('.field-validation-error').removeClass('field-validation-error').addClass('field-validation-valid');
        var container = jForm.find("[data-valmsg-summary=true]");
        list = container.find("ul");
        list.empty();
        if (errors.length > 0) {
            $.each(errors, function (i, ival) {
                $.each(ival.errors, function (j, jval) {
                    $("<li />").html(jval).appendTo(list);
                });
    
            });
            container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
            inner_ServerErrors(errors);
            setTimeout(function () { jForm.find('span.input-validation-error[data-element-type]').removeClass('input-validation-error') }, 0);
        }
        else {
            container.addClass("validation-summary-valid").removeClass("validation-summary-errors");
        }
    }
    function clearErrors(jForm) {
        remoteErrors(jForm, []);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-12
      • 1970-01-01
      • 2011-09-23
      • 2012-04-28
      • 1970-01-01
      • 1970-01-01
      • 2011-08-30
      • 2016-09-19
      相关资源
      最近更新 更多