【问题标题】:how does the __doPostBack method get called? Where is the calling method?__doPostBack 方法是如何被调用的?调用方法在哪里?
【发布时间】:2013-03-18 16:37:41
【问题描述】:

我使用了<asp:Button /> 控件,在浏览器中呈现后,该控件没有分配click 事件属性。它究竟是如何调用服务器端事件的?

ASPX 代码:

<asp:Button ID="Button1" runat="server" Text="Button" OnClick="TestClickEvent" />

上述控件在浏览器中呈现为如下代码:

<input type="submit" name="Button1" value="Button" id="Button1">

以下代码在浏览器中呈现,设置__EVENTTARGET我的疑问是__doPostBack 方法是如何被调用的?调用方法在哪里?

 function __doPostBack(eventTarget, eventArgument) {
        if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
            theForm.__EVENTTARGET.value = eventTarget;
            theForm.__EVENTARGUMENT.value = eventArgument;
            theForm.submit();
        }
    }

【问题讨论】:

  • 请向我们展示您的代码
  • “在浏览器中呈现后” 我认为您混淆了服务器端和客户端代码。
  • 我认为你应该阅读这个support.microsoft.com/kb/306459 它解释了 Web 窗体服务器端控件。本质上,回发是通过 javascript 完成的,__EVENTTARGET 和 __VIEWSTATE 隐藏字段分别保存有关单击的内容和页面上的数据的信息。在幕后 __EVENTTARGET 等被询问并调用适当的服务器端事件处理程序。
  • 如您所见,您的按钮是“提交”。您呈现的 HTML 源代码中的 asp.net 表单标记会捕获此提交,并知道发件人是谁,因此它可以触发正确的事件
  • 在提交按钮回发期间,它不是必需的。当 ASP.NET Framework 接收到带有空的 __EVENTTARGET__EVENTARGUMENT 的 POST 时,它自动知道提交按钮导致了回发。

标签: c# asp.net webforms asp.net-ajax


【解决方案1】:

你的控件是一个提交按钮,它可以直接将表单提交到服务器,而不需要调用__dopostback方法。所以在这种情况下 __dopostback 不会被调用。 __dopostback 用于没有默认提交行为的控件,例如下拉列表。

通过控件实现的 ipostbackeventhandler 接口连接到服务器端事件。欲了解更多信息,请查看此http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackeventhandler.raisepostbackevent.aspx

【讨论】:

  • 不调用 _dopostback 方法,如何初始化 __EVENTTARGET 值。
  • 它不会被初始化也不需要它,因为按钮直接提交表单,而不是通过_dopostback,asp.net框架知道谁触发了事件,它会调用ipostbackeventhandler接口RaisePostBackEvent方法,将其连接到按钮的点击事件
【解决方案2】:

简单的答案:__doPostBack JavaScript 函数是根据特定的&lt;asp /&gt; 控件调用它处理的事件。

详细答案:视情况而定。


首先,让我们介绍一下您的示例。您有一个&lt;asp:Button /&gt;,它被呈现为标准&lt;input type="submit" /&gt;ASP.NET WebForms 中的所有内容都围绕标准的 HTML &lt;form&gt; 标签。通过单击 &lt;input type="submit" /&gt; 按钮提交 HTML &lt;form&gt;无需使用或帮助 JavaScript。

考虑到这一点,您可以很好地看到(您已经注意到)渲染的&lt;input type="submit" /&gt; 按钮确实没有分配了onclick 事件。而且,如您所见,单击按钮时会提交表单。

关于点击&lt;input type="submit" /&gt;按钮时后端(C#/VB.NET/etc.)代码如何执行:都是由ASP.NET Framework自己处理的,超出了范围这个问题/答案。


其次,现在让我们介绍一下__doPostBack 是什么,以及它是如何使用的。 __doPostBack 只是一个用于提交HTML &lt;form&gt; 的辅助JavaScript 函数。由于上述原因,您现在知道为什么&lt;input type="submit" /&gt; 按钮不需要 需要调用__doPostBack 函数。

为简单起见,让我们看一下具有&lt;asp:DropDownList /&gt; 控件并分配了SelectedIndexChanged 事件处理程序的ASP.NET 页面:

<asp:DropDownList ID="MyDropDownList" AutoPostBack="true" OnSelectedIndexChanged="MyDropDownList_SelectedIndexChanged" runat="server" />

&lt;asp:DropDownList /&gt; 呈现如下:

<select id="ctl00_MyDropDownList" onchange="javascript:setTimeout('__doPostBack(\'ctl00$MyDropDownList\',\'\')', 0)" name="ctl00$MyDropDownList"></select>

让我们忽略 onchange 事件中的 setTimeout 函数 - 它只是 ASP.NET 使用的一种 hacky 解决方法 - 让我们关注其中的 __doPostBack 函数。

正如您在此处看到的,__doPostBack 函数 正在onchange 事件处理程序调用。主要区别在于更改&lt;asp:DropDownList /&gt;&lt;select /&gt; 控件的值不会导致浏览器提交表单!

ASP.NET Framework 再次在内部处理提交表单时后端代码的执行方式(无论是否通过__doPostBack 函数)。


最后,关于__doPostBack的细节:它接受两个参数——eventTargeteventArgumenteventTarget 包含导致回发的控件的呈现 HTML id 属性;而eventArgument 是一个可选参数,可用于将附加数据传递给后端代码。


编辑附加信息: OP 提出了一个非常有趣的问题 - 当有多个提交按钮时会发生什么?

好吧,在POST 操作期间,浏览器包含导致操作启动的&lt;input type="submit" /&gt;value

这意味着,就像您获取&lt;input /&gt; 元素的值一样,您还可以查询是哪个按钮导致了提交!

【讨论】:

  • 哇真的很喜欢这个解释,过去 5 年一直在使用 ASP.NET,但没有尝试了解它在这些细节上的实际工作原理!!!
【解决方案3】:

嗯,你有疑问的原因是因为你认为函数 __doPostBack 需要发布。但反过来,当 html 最初设计时,回发到服务器的唯一方法是通过提交按钮。此功能是在浏览器中构建的,因此当按下提交按钮时,浏览器会将表单的数据传递到声明的位置。但随着网络的发展,人们开始要求更多。现在其他控件也需要回发到服务器。为了实现它们,开发了各种 hack,最著名的 __doPostBack 函数就是其中之一。现在提交的任何其他控件都可以使用 __doPostBack 函数回发。但是提交按钮自己做。就是这样。

【讨论】: