一个ASP.NET页面如何知道哪个按钮触发了回传?

5
我正在编写一些代码,模拟通过执行与单击触发页面回发的按钮相同的网络请求来产生回发效果。但问题是,当我执行网络请求时,响应与单击按钮时得到的不同。
经过调查,我发现即使在执行网络请求时触发并处理了Page_Load事件,但按钮点击的处理程序并未被执行(这意味着要么事件没有被触发,要么已被触发但未被处理——我猜测更可能是前者)。
所以我的问题是 - ASP.NET如何知道单击了哪个按钮,以便调用适当的处理程序?
我认为这是通过使用__EVENTTARGET参数来完成的 - 我已经在Web请求的正文中正确设置了此参数,但这没有任何影响。
我查看了解码后的__VIEWSTATE参数,但我在其中找不到任何明显的内容。
有人能提供进一步的帮助吗?
编辑:为了明确起见,我是在问如何向Web应用程序添加单击处理程序。
相反,我正在查看一个已经具有按钮单击事件处理程序的应用程序,并且我想知道ASP.NET如何从传入的Web请求中找出哪个按钮单击事件处理程序代码要调用。

你能否提供更多关于你如何发起网络请求的细节?是使用C#代码、jQuery还是JavaScript?你是否在网络请求中传递了_Viewstate?你看到了什么错误? - Raj Kaimal
我正在使用C#。我的做法是,我首先向一个页面发出初始请求,并在响应中获取__VIEWSTATE元素。然后,在我生成的Web请求中模拟回发时,我传递了这个__VIEWSTATE的值。我没有看到错误 - 我只看到当我在服务器代码上设置断点时,处理服务器上按钮点击的代码没有被调用。 - Tola Odejayi
7个回答

7
首先,ASP.NET按钮<asp:button>会以一个<input type="submit" runat="server"...>元素的形式呈现在表单上。关于postbacks,与其他控件相比,该按钮的行为有所不同。
当点击<input type="submit"...>时,它将自动触发一个postback而无需ASP.NET的帮助(在.htm文件中尝试)。您可以通过查看POST正文的参数来确定哪个按钮被单击。按钮名称及其值(Text prop.)将作为参数发送。__EVENTTARGET不在图片中,应为null。此外,根据规范,在参数列表中只有一个按钮控件(即被单击的按钮)。因此,现在您知道了哪个按钮被单击了。
那么__EVENTTARGET有什么用处呢?
其他控件,如渲染为SELECT<asp:DropDownList>,在单击时不会触发postback,而只是引发onChange javascript事件。如果您想通过SelectedIndexChanged事件在服务器端处理事件,ASP.NET将不得不为您做一些额外的工作。如果您为DropDownList设置AutoPostBack = True,则ASP.NET将捕获原始的onChange JS事件,并连接一个自定义的__doPostBack JS函数,负责填充__EVENTTARGET并显式地提交表单。现在,您可以通过检查__EVENTTARGET来确定触发postback的控件。
希望这有所帮助!

2

我无法回答你的问题,但是我可以告诉你如何找到答案。

在你的page_load函数中添加一行代码:Request.SaveAs(@"c:\temp\request.txt", true); (以此为例)

然后点击按钮进行postback操作。

接着读取request.txt文件的内容。里面是否有任何有用或者有趣的信息呢?


1
谢谢,Wozza。我会尝试一下并告诉你我发现了什么。 - Tola Odejayi

0

看起来只需要发布带有要单击的按钮的ID的__EVENTTARGET值。您必须设置EnableEventValidation="false",否则ASP.NET会抛出错误。请查看此示例。普通HTML页面,发布到asp.net页面,模拟单击该页面上的按钮,这应该类似于您要尝试的操作。

HTML页面:

<html xmlns="http://www.w3.org/1999/xhtml">
<body>
    <form action="Default.aspx" method="post">
    <input value="cmdSubmit" name="__EVENTTARGET" type="hidden" />
    <input type="submit" value="submit" />
    </form>
</body>
</html>

带有点击按钮的ASP.NET页面(Default.aspx):

<%@ Page Language="C#"  EnableEventValidation="false"    %>
<script runat="server">

    protected void cmdSubmit_Click(object sender, EventArgs e)
    {
        litResult.Text = "Submit button clicked";
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<body>
    <form id="form1" runat="server">
    <asp:Literal ID="litResult" runat="server" EnableViewState="false"></asp:Literal>
    <asp:Button UseSubmitBehavior="false" ID="cmdSubmit" EnableViewState="false" runat="server"
        OnClick="cmdSubmit_Click" Text="Submit" />
    </form>
</body>
</html>

Chris,我可能会生成JavaScript代码 - 但这如何回答我的问题,即ASP.NET如何知道触发特定的事件处理代码? - Tola Odejayi
1
我看到JavaScript通过设置被单击控件的ID来设置__EVENTTARGET隐藏字段的值,然后提交表单。但是这可能不仅仅是这样,比如ViewState字段为空就无法表示它是一个PostBack。 - Chris Mullins
这是个好观点,Chris,我也是这么想的。我检查了点击按钮时生成的请求的__EVENTTARGET字段,并且它有被点击的按钮的ID。然后我确保我的请求具有相同的__EVENTTARGET值,但似乎这并没有触发按钮单击事件处理程序。所以也许还有更多的东西。我希望有人能在这里提供更多的信息... - Tola Odejayi
我进行了一些测试并更新了我的答案。我能够从一个普通的HTML页面发布到asp.net页面并触发按钮点击事件。 - Chris Mullins

0

好的,最终我解决了这个问题。

请求应该包含一个名称值对,其中名称是所点击按钮的ID,而值可以是“1”。

让我困惑的是,在点击按钮生成的请求中,我没有看到这样的名称值对。真的很奇怪。

尽管如此,将此名称值对添加到我的创建的Web请求中,导致按钮单击事件处理程序代码被触发。


0

0
在您的代码后台,您必须有一个事件进行处理,而且该事件必须具有 Handles ButtonName.Click
例如:
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button2.Click
    ''# Process everything you want to process when Button2 gets clicked
End Sub

或者,在您的按钮中,您可以在标记中设置OnClick

<asp:button ID="Button2" runat="server" OnClick="Button2_Click" Text="Click Me" />

因为按钮设置了 runat="server",.NET 将会为您处理所有繁重的工作。


嗨,Rockinthesixstring,就像我对上面的Cylon Cat所说的那样,我不想处理点击事件 - 我只是想弄清楚为什么在调用与按钮单击调用相同的请求时现有的单击事件没有触发。如果我知道asp.net在Web请求中寻找哪些内容以便调用单击处理程序代码,那么我将添加这些内容到Web请求中 - 因此我的最初问题是关于asp.net如何解析发送的Web请求以找出要调用哪个处理程序。 - Tola Odejayi

0

有许多简单的方法可以为按钮创建事件处理程序。在布局模式下,双击按钮。或者,在布局模式下选择按钮,打开属性窗口,单击“闪电”图标,然后查看控件可以触发的事件列表。双击您想要的事件。

当您执行其中之一时,Visual Studio将在您的代码后台中创建事件处理程序,并连接事件。

按钮事件处理程序在页面加载后运行,并在使用ASP.NET验证器时进行页面验证。


嗨,Cylon Cat,我不想为按钮创建事件处理程序。相反,我想在一个 Web 应用程序中执行服务器代码,该代码应该处理按钮单击。我想通过调用与单击按钮时生成的 Web 请求完全相同的 Web 请求来实现这一点。我相信这样做应该会导致调用按钮单击处理程序代码,但事实并非如此。因此,我想知道 asp.net 在 Web 请求中寻找什么,以便确定应调用哪个事件处理程序代码。 - Tola Odejayi
Web请求的处理方式与按钮点击截然不同,因此如果您想将其视为Web请求,则可以采用两种方法。一种是使用Page Methods,另一种是创建Web服务。我没有使用过Page Methods,但它们是页面内可调用的AJAX方法,您需要使用asp:ScriptManager标记指定您要使用Page Methods。如果您创建了一个Web服务,服务代码将在ASP.NET会话中运行,并可以访问会话变量。您可以在asp:ScriptManager中编写服务引用;这使得服务可从JavaScript调用。 - Cylon Cat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接