MVC4 不显眼的验证不等待远程验证完成

Posted

技术标签:

【中文标题】MVC4 不显眼的验证不等待远程验证完成【英文标题】:MVC4 unobtrusive validation doesn't wait for remote validation to be completed 【发布时间】:2013-10-17 10:19:03 【问题描述】:

我的 ASP.NET MVC4 应用程序有一个在模型中定义并在控制器方法中实现的远程验证规则。我的表单是动态添加到页面中的。所以,我使用下面的代码来触发验证。

$(tabId).on("submit", formId, function (event) 
       event.preventDefault();

       var form = $(this);

       form.removeData("validator"); 
       $.validator.unobtrusive.parse(form);

       if (form.valid())
       
           // form submission 

           // THIS part executes even though the remote validation returns false
       

       return false;
 );

它开始远程验证并且不等待完成然后提交表单。如果任何其他字段无效(例如,名称是必填字段),则会停止提交。但是,它不会等待远程验证。

我在 SO 上找到了一些解决方法,例如 link1 和 link2。但是,这些只有在我的页面中定义了 jQuery 验证规则时才有效。但是,我使用的是 MVC4 模型验证规则。因此,我没有兴趣再次在我的视图页面中重新定义规则。

有什么解决办法吗?

【问题讨论】:

你有没有试过在if (form.valid())之前打电话给form.validate() 是的,我试过form.validate()。它没有用。 @NRocking 你找到解决方案了吗?我正在寻找它的解决方案。 【参考方案1】:

您可以使用验证器上的 pendingRequest 变量来查看当表单尝试提交时是否还有待处理的内容

$(tabId).on("submit", formId, function (event) 
       event.preventDefault();
       var form = $('#formid');
       form.removeData("validator"); 
       $.validator.unobtrusive.parse(form);

       if (form.valid() && form.data('validator').pendingRequest == 0)
       
           // form submission 
        
       return false;         
);  

如果您想在字段验证时向用户显示消息,您可以使用 startrequest 和 stopRequest 函数:

$(function()
    var validator = $('#formid').data('validator');

    var oldStartRequest = validator.startRequest;
    validator.startRequest = function (element)      
        console.log(element.name + ' has begun validating')
        oldStartRequest.apply(this, arguments);
    ;

    var oldStopRequest = validator.stopRequest;
    validator.stopRequest = function (element, valid) 
        console.log(element.name + ' has finished validating');
        console.log(element.name + ' is valid: ' + valid)
        oldStopRequest.apply(this, arguments);
    ;
);

【讨论】:

【参考方案2】:

您应该在表单添加到页面后立即致电$.validator.unobtrusive.parse(form)。在提交事件中调用它是不正确的,很可能是您的问题。 Validator 和 Unobtrusive 所做的其中一件事就是为您捕获这些事件,并且由于 Unobtrusive 的工作方式,如果您想在成功提交时执行特定操作,您必须偷偷地将自己附加到 submitHandler,如下所示:

$('#nameForm').data('validator').settings.submitHandler = function(form)
   alert('successful submit'); 

   //do AJAX submit here

   return false; //otherwise page will get reloaded
;

我为您做了一个工作示例,但请注意,由于 jsfiddle 的工作方式,执行 AJAX 调用有些困难,因此我必须添加一个名为 html 的隐藏字段,如果您更改值在真假之间,你可以看到不同的行为。

http://jsfiddle.net/ryleyb/ZeZAu/1/

【讨论】:

Helpful discussion 如何处理不会破坏 Validate/Unobtrusive 工作方式的有效/无效表单【参考方案3】:

您可以附加到global ajax events 并确保在您提交表单时没有等待回复。未经测试,例如

var isInAjaxCall = false;
var queuedFuncs = [];
$(function() 
    $(document).bind("ajaxStart", function () 
        isInAjaxCall = true;
     ).bind("ajaxStop", function () 
        isInAjaxCall = false;
        while(queuedFuncs.length > 0)
           queuedFuncs.shift();
        
    );
);

function SubmitForm() 
    if (isInAjaxCall) 
        queuedFuncs.push('SubmitForm');
        return false;
    

    var form = $('#form');
    form.removeData("validator");
    $.validator.unobtrusive.parse(form);

    if (form.valid()) 
        // form submission 
    
    return false;

【讨论】:

【参考方案4】:

我这里的帖子提供了解决方案,但一定有更好的方法:

ASP.NET-MVC jQuery unobtrusive remote validation returns false positives

【讨论】:

以上是关于MVC4 不显眼的验证不等待远程验证完成的主要内容,如果未能解决你的问题,请参考以下文章

Jquery post和不显眼的ajax验证不起作用mvc 4

ASP.NET-MVC jQuery 不显眼的远程验证返回误报

在 MVC 4.0 站点中升级 jQuery 1.9 时不显眼的 jQuery 失败

mvc4 remote 远程验证无法响应

在ASP.NET MVC4中如何执行远程验证?

使用 jQuery 进行 MVC 手动表单验证始终返回 True