__DoPostback在执行部分回发时回发禁用控件的值

时间:2009-09-16 20:53:47

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

我有一个表单,为了隔离问题,它有大约十几个纯HTML复选框(不是WebControls),所有这些都是禁用。它们在UpdatePanel内。

我有一个叫

的链接
  

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

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

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

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

这很烦人,我希望它表现得一致。反正有没有告诉.NET javascript处理程序按照世界其他地方的方式工作, postback 禁用 HTML表单元素的值?< / p>

3 个答案:

答案 0 :(得分:3)

对我来说看起来像个错误。根据{{​​3}},禁用的输入应与表单一起提交。

这是我完整的测试页面:

<%@ 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. 再次点击“提交外部UpdatePanel”。请注意,POST主体中省略了参数"foo"。这是预期的。
  5. 点击“提交内部UpdatePanel”(触发部分回发)。请注意,POST主体中存在值"foo=on",即使应该已被省略

  6. 该错误似乎同时出现在 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属性被完全忽略,违反了表单提交实现的规范和事实上的行为。

答案 1 :(得分:2)

在.Net中,form标签具有submitdisabledcontrols属性,默认为false。如果将其设置为true,则至少可以使事情始终如一。

答案 2 :(得分:2)

我可以提出两个选择:

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

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

Sys.WebForms.PageRequestManager.getInstance()._ onFormSubmit = function ...

然后将此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);
}

像魅力一样!