Asp.net Page_ClientValidate阻止后续(不相关)链接按钮客户端单击发回

Asp.net Page_ClientValidate阻止后续(不相关)链接按钮客户端单击发回,asp.net,webforms,asp.net-4.6,Asp.net,Webforms,Asp.net 4.6,TL;DR:如果在没有选择列表框的情况下单击编辑按钮,会触发验证失败,为什么在浏览器响应之前需要单击两次删除链接 使用下面的源代码创建一个非常简单的菜单,我有三个链接: New-不执行验证并重定向到“创建”表单 Edit-检查是否选择了ListItem,如果选择了,则将ID值作为参数重定向到“Edit”表单 Delete-重定向到“Delete”页面,无论是否进行了选择 我注意到一个奇怪的行为,并在这个简单的单页解决方案()中重现: 加载页 单击Edit,而不从列表框中进行选择(出现验证错误)

TL;DR:如果在没有选择列表框的情况下单击编辑按钮,会触发验证失败,为什么在浏览器响应之前需要单击两次删除
链接

使用下面的源代码创建一个非常简单的菜单,我有三个链接:

  • New
    -不执行验证并重定向到“创建”表单
  • Edit
    -检查是否选择了ListItem,如果选择了,则将ID值作为参数重定向到“Edit”表单
  • Delete
    -重定向到“Delete”页面,无论是否进行了选择
  • 我注意到一个奇怪的行为,并在这个简单的单页解决方案()中重现:

  • 加载页
  • 单击
    Edit
    ,而不从列表框中进行选择(出现验证错误)
  • 单击
    删除
    -什么都没有发生-为什么
  • 单击
    Delete
    -服务器端重定向成功发生,但这应该发生在上面的步骤3中
  • 以下是在我的浏览器中发生的情况(在Chrome、FF和Edge中进行了测试)-请注意,需要在删除链接上单击两次:

    更新 问题似乎出现在ASP.Net的表单提交代码中:

    function __doPostBack(eventTarget, eventArgument) {
        if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
    
        // On first click - this logic path is never reach, but on the second click, it is reached
    
            theForm.__EVENTTARGET.value = eventTarget;
            theForm.__EVENTARGUMENT.value = eventArgument;
            theForm.submit();
        }
    }
    
    在我手动调用
    Page\u ClientValidate()
    之后,我试图找出
    if
    语句返回false的原因

    代码
    
    测试页
    函数RedirectToPageWithSelectedId(){
    if(Page_ClientValidate(“mustSelect”){//Asp.Net客户端验证,将ValidationGroup作为参数传递
    var li=$(“#选项:选定”);
    var i=li.val();
    if(parseInt(i)!=NaN){
    window.location.href=“/edit/”+i;
    }
    }
    }
    
    


    如果需要,我可以更新以提供页面的代码;问问吧

    我会这样做。为包含元素的
    指定一个类名,并按类绑定
    lnk\u edit
    的点击。现在,您可以在不必使用
    ClientID
    的情况下找到是否选择了元素。这也适用于任意多个
    myContainer
    副本,而无需添加更多jQuery代码

    <div class="myContainer">
        <p>
            <asp:ListBox ID="ListBox1" runat="server" />
        </p>
        <ul>
            <li>
                <asp:HyperLink ID="lnk_new" runat="server" Text="New" NavigateUrl="~/new" />
            </li>
            <li>
                <asp:HyperLink ID="lnk_edit" runat="server" Text="Edit Selected" href="#" CssClass="myEditLink" />
                <span class="myEditLinkWarning"></span>
            </li>
            <li>
                <asp:LinkButton ID="lnk_delete" runat="server" Text="Delete" />
            </li>
        </ul>
    </div>
    
    <script type="text/javascript">
        $('.myContainer .myEditLink').click(function () {
            $(this).closest('div').find('select option').each(function () {
                if ($(this).prop('selected')) {
                    window.location.href = "/edit/" + $(this).val();
                }
            });
            $(this).closest('div').find('.myEditLinkWarning').html('Please select');
        });
    </script>
    
    
    
    

    $('.myContainer.myEditLink')。单击(函数(){ $(this).最近的('div').find('select option').each(函数(){ if($(this.prop('selected')){ window.location.href=“/edit/”+$(this.val(); } }); $(this).closest('div').find('.myEditLinkWarning').html('Please select'); });
    在使用Chrome的调试器进行了大量调查之后,我发现了以下逻辑和解决方法。如果我弄错了,请告诉我,或者是否有更好的方法在客户端与ASP.Net的验证控件交互

    单击LinkButton时,ASP.Net通过其验证逻辑工作,即使该控件未导致验证。这是让我吃惊的第一件事。在处理验证逻辑之前,不会实际提交表单

    ASP.NETWebForms客户端验证 在验证期间,将设置两个页面级变量:

    页面有效

    这是一个总体布尔值,指示所有验证器都有效

    页面提交

    这通常与
    Page\u是有效的
    的值相反,如果
    true
    ,则阻止表单提交

    代码中的问题 单击“我的<代码>编辑链接”时,我的代码触发了特定验证组的客户端验证:

    Page_ClientValidate("mustSelect");
    
    在该方法中,
    Page\u是有效的
    变为
    false
    ,因此
    Page\u BlockSubmit
    变为
    true
    。这将防止窗体在显示验证错误后执行任何操作,这是预期的

    LinkButton的click事件会出现问题。按下时,无论LinkButton是否正在执行验证,都会执行以下JavaScript:

    function __doPostBack(eventTarget, eventArgument) {
        if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
    
            // This is never reached if Page_BlockSubmit = true
    
            theForm.__EVENTTARGET.value = eventTarget;
            theForm.__EVENTARGUMENT.value = eventArgument;
            theForm.submit();
        }
    }
    
    更重要的是,以前的验证结果仍然保存在浏览器中,因此
    Page\u BlockSubmit
    仍然是
    true
    。这会导致上述方法跳过提交表单的内部代码,这意味着表单永远不会被提交

    奇怪的是,在方法完成后,
    Page\u是有效的
    Page\u BlockSubmit
    都被重置为默认值。这就是为什么页面在第二次编辑点击时提交

    解决方法(还是肮脏的黑客?) 这感觉像是一次彻底的黑客攻击,但通过在单击链接按钮时强制将
    Page\u BlockSubmit
    的值设为false,一切都按预期进行,并且无需手动开始重置
    验证。isvalid
    属性或隐藏消息。所有其他验证组/逻辑继续正常工作,但“编辑”链接现在可以按照用户的预期工作:

    <asp:LinkButton ID="lnk_delete" runat="server" Text="Delete" OnClientClick="Page_BlockSubmit = false;" />
    
    
    

    同样,我不知道这是否会扰乱ASP.Net的任何工作,我希望您能提供任何信息。

    我无法重现这个问题。一切都按它应该的那样运作。“删除”按钮在第一次尝试时起作用。您确定要先单击“编辑”按钮,触发验证失败,然后删除吗
    <asp:LinkButton ID="lnk_delete" runat="server" Text="Delete" OnClientClick="Page_BlockSubmit = false;" />