【问题标题】:__DoPostback posts back the values of disabled controls when doing a partial postback__DoPostback 在进行部分回发时回发禁用控件的值
【发布时间】:2010-11-28 22:56:03
【问题描述】:

我有一个表单,为了隔离问题,它有大约十几个普通的 HTML 复选框(不是 WebControl),所有这些都禁用。它们位于UpdatePanel 中。

我有一个链接调用

__doPostBack('a-control','my-custom-argument');

根据我提供的第一个参数,页面可能是完整的postback 或部分的。

当我完成一个完整的postback 时,帖子中没有一个复选框值被提交(因为它们被禁用)。这是正常,因此是期望的行为。

但是,当它执行部分postback 时,该脚本会从我的复选框中收集所有值并提交它们,但不会指出哪些值被禁用,这会破坏我的代码。

这很烦人,我希望它表现得始终如一。有没有办法告诉 .NET javascript 处理程序按照世界其他地方的方式工作,不是 postback disabled HTML 表单元素的值?

【问题讨论】:

    标签: javascript asp.net ajax asp.net-ajax webforms


    【解决方案1】:

    对我来说似乎是一个错误。根据this禁用的输入应该不与表单一起提交。

    这是我的完整测试页面:

    <%@ Page Language="C#" AutoEventWireup="true" Inherits="System.Web.UI.Page" EnableViewState="false" EnableEventValidation="false" Trace="false" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head>
        <title>Test disabled checkboxes</title>
        <script>
        initState = false;
        function disableCheckboxes(disabled) {
            document.getElementById('foo').disabled = disabled;
        }
        </script>
    </head>
    <body>
    <form id="form1" runat="server">
        <asp:ScriptManager runat="server" />
    
        <asp:UpdatePanel runat="server">
            <ContentTemplate>
                <input runat="server" type="checkbox" id="foo" name="foo" checked="checked" /> Foo
                <asp:Button ID="Inside" runat="server" Text="Submit Inside UpdatePanel" />
            </ContentTemplate>
        </asp:UpdatePanel>
    
        <asp:Button ID="Outside" runat="server" Text="Submit Outside UpdatePanel" />
        <br />
        <button type="button" onclick="disableCheckboxes(initState=!initState)">Toggle checkboxes</button>
    </form>
    </body>
    </html>
    

    重现步骤:

    1. 打开 Fiddler 和测试页面。
    2. 单击“在 UpdatePanel 外部提交”(触发正常的回发)。请注意,在 Fiddler 中,值 "foo=on" 在 POST 正文中提交。
    3. 单击“切换复选框”以禁用复选框。
    4. 再次单击“在更新面板外部提交”。请注意参数"foo" 从POST 正文中省略。这是意料之中的。
    5. 单击“在 UpdatePanel 内提交”(触发部分回发)。请注意,POST 正文中存在值 "foo=on",即使它应该被省略

    该错误似乎存在于 MicrosoftAjaxWebForms.js 和 MicrosoftMvcAjax.js(以及每个对应的 .debug)中:

    if ((type === 'text') ||
        (type === 'password') ||
        (type === 'hidden') ||
        (((type === 'checkbox') || (type === 'radio')) && element.checked)) {
            formBody.append(encodeURIComponent(name));
            formBody.append('=');
            formBody.append(encodeURIComponent(element.value));
            formBody.append('&');
    }
    

    被序列化的元素的disabled 属性被完全忽略,违背了表单提交实现的规范和事实上的行为。

    【讨论】:

      【解决方案2】:

      我可以建议两个选项:

      1) 您可以在回发之前使用 JavaScript 删除禁用控件的 name 属性。

      2) 使用更正的代码版本覆盖 Sys.WebForms.PageRequestManager.getInstance()._onFormSubmit。只需从MicrosoftAjaxWebForms.debug.js 复制实现,添加对disabled 属性的处理并将更正的函数附加到现有的PageRequestManager 对象:

      Sys.WebForms.PageRequestManager.getInstance()._onFormSubmit = 函数...

      然后将这个 JS 块注册为启动脚本。获得渲染脚本块的正确顺序很重要。我在我的 ScriptManager 子类中做了类似的事情:

      protected override void OnResolveScriptReference(ScriptReferenceEventArgs e) {
          base.OnResolveScriptReference(e);
      
          if (e.Script.Name.StartsWith("MicrosoftAjax"))
              Page.ClientScript.RegisterStartupScript(GetType(), "My patch", MyPatchJs, true);
      }
      

      像魅力一样工作!

      【讨论】:

        【解决方案3】:

        在 .Net 中,表单标签具有 submitdisabledcontrols 属性,默认为 false。如果您将其设置为 true,您至少可以使事情表现一致。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-04-05
          • 1970-01-01
          • 2016-10-03
          • 1970-01-01
          • 1970-01-01
          • 2012-04-20
          • 1970-01-01
          相关资源
          最近更新 更多