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

Posted

技术标签:

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

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

我有一个链接调用

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

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

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

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

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

【问题讨论】:

【参考方案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>

重现步骤:

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

该错误似乎存在于 MicrosoftAjaxWebForms.jsMicrosoftMvcAjax.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,您至少可以使事情表现一致。

【讨论】:

以上是关于__DoPostback 在进行部分回发时回发禁用控件的值的主要内容,如果未能解决你的问题,请参考以下文章

避免在部分回发时重复样式

回发时的 ASP.Net 复选框值错误?

在链接中使用模式时如何进行回发

jQuery填充的Gridview在回发时丢失数据

使用 JavaScript 回发抓取 HTML

如何执行用于提高回发的 javascript 代码