__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.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,您至少可以使事情表现一致。
【讨论】:
以上是关于__DoPostback 在进行部分回发时回发禁用控件的值的主要内容,如果未能解决你的问题,请参考以下文章