【问题标题】:How does an asp.net page know which button triggered a postback?asp.net 页面如何知道哪个按钮触发了回发?
【发布时间】:2010-06-29 00:06:29
【问题描述】:

我正在编写一些代码,通过执行与单击触发页面回发的按钮时生成的完全相同的 Web 请求来模拟回发到页面的效果。

问题是来自网络请求的响应与单击按钮时得到的响应不同。

在调查时,我发现即使在我执行 Web 请求时触发并处理了 Page_Load 事件,按钮单击的处理程序也没有被执行(这意味着事件没有被触发,或者它被触发但是未处理 - 我猜这更有可能是前一种情况)。

所以我的问题是 - ASP.NET 如何知道单击了哪个按钮,以便它可以调用适当的处理程序?

我认为这是通过使用 __EVENTTARGET 参数完成的 - 我已在 Web 请求的帖子正文中正确设置了它,但这没有任何区别。

我查看了解码后的 __VIEWSTATE 参数,但看不到任何明显的内容。

谁能提供进一步的帮助?

编辑:为了清楚起见,我不是询问如何将点击处理程序添加到 Web 应用程序。

相反,我正在查看一个已经具有按钮单击事件处理程序的应用程序,并且我想知道 asp.net 如何从传入的 Web 请求中计算出哪个按钮单击事件处理程序代码调用。

【问题讨论】:

  • 您能否详细说明您是如何进行网络请求的?使用 C# 代码或 jquery 或 javascript?您是否将 _Viewstate 与 Web 请求一起传递?你看到了什么错误?
  • 我正在使用 C#。我正在做的是向页面发出初始请求,并在响应中取回 __VIEWSTATE 元素。然后在我为模仿回发而生成的 Web 请求中,我传递了这个 __VIEWSTATE 的值。我没有看到错误 - 我所看到的只是当我在服务器代码上放置断点时,没有调用处理服务器上按钮单击的代码。

标签: asp.net httpwebrequest


【解决方案1】:

首先,一个 ASP.NET 按钮 <asp:button> 在表单上呈现为一个 <input type="submit" runat="server"...> 元素。关于回发,与其他控件相比,此按钮的行为有所不同。

当点击<input type="submit"...> 时将自动触发回发无需 ASP.NET 的帮助(在 .htm 中尝试)。您可以通过查看 POST 正文的参数来确定单击了哪个按钮。按钮名称及其值(Text prop.)将作为参数发送。 __EVENTTARGET 不在图片中,应该为空。此外,根据规范(单击的那个),参数列表中将只有一个按钮控件。所以现在你知道点击了哪个按钮。

那么__EVENTTARGET有什么用呢?

其他控件,例如呈现为SELECT<asp:DropDownList>,在单击时不会触发回发,而只是引发onChange javascript 事件。如果您想通过SelectedIndexChanged 事件在服务器端处理事件,ASP.NET 将不得不为您做一些额外的工作。如果为 DropDownList 设置 AutoPostBack = True,ASP.NET 将捕获原始 onChange JS 事件并连接一个自定义 __doPostBack JS 函数,该函数负责填充 __EVENTTARGET 并显式提交表单。您现在可以通过检查 __EVENTTARGET 来确定触发回发的控件。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

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

    在您的 page_load 中添加一行:Request.SaveAs(@"c:\temp\request.txt", true); (例如)。

    然后单击您的按钮以实现回发。

    然后读取request.txt的内容。里面有什么有用或有趣的东西吗?

    【讨论】:

    • 谢谢,沃扎。我会试一试,让你知道我发现了什么。
    【解决方案3】:

    在你的代码中,你必须有一个事件来处理,并且那个事件必须有Handles ButtonName.Click

    IE:

    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 所说的那样,我不想处理点击事件 - 我只想弄清楚为什么当我调用 Web 请求时现有的点击事件没有触发这与单击按钮时调用的请求相同。如果我知道 asp.net 在 web 请求中究竟在寻找什么以调用点击处理程序代码,那么我会将它添加到 web 请求中——因此我最初的问题是关于 asp.net 如何解析 web 请求发送以确定调用哪个处理程序。
    【解决方案4】:

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

    当您执行其中一项操作时,Visual Studio 将在您的代码隐藏中创建事件处理程序,并连接事件。

    按钮事件处理程序在页面加载后运行,如果您使用的是 ASP.NET 验证器,则在页面验证后运行。

    【讨论】:

    • 嗨 Cylon Cat,我不想想为按钮创建事件处理程序。相反,我想在应该处理按钮单击的 Web 应用程序中练习服务器代码。我想通过调用与单击按钮时生成的 Web 请求相同的 Web 请求来做到这一点。我相信这样做应该会导致调用按钮单击处理程序代码,但这并没有发生。所以我想知道 asp.net 在 Web 请求中查找什么,以便确定应该调用哪些事件处理程序代码。
    • Web 请求的处理方式与按钮单击的处理方式非常不同,因此如果您想将其视为 Web 请求,您可以采用两种方式。一种是使用页面方法,另一种是创建 Web 服务。我没有使用页面方法,但它们是页面中的 AJAX 可调用方法,您需要一个 asp:ScriptManager 标记来指定您将使用页面方法。如果创建 Web 服务,服务代码将在 ASP.NET 的会话中运行,并且可以访问会话变量。您可以在 asp:ScriptManager 中编写服务引用;这使得服务可以从 JavaScript 调用
    【解决方案5】:

    看起来实际上只有 __EVENTTARGET 值需要与您要单击的按钮的 ID 一起发布。您必须设置 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>
    

    【讨论】:

    • 克里斯,我可能会生成 javascript - 但这将如何回答我关于 asp.net 如何知道如何触发特定事件处理代码的问题?
    • 在我看来,javascript 正在使用正在单击的控件的 ID 设置 __EVENTTARGET 隐藏字段的值,然后提交表单。但可能不止这些,比如 viewstate 字段不能为空以表明它是回发。
    • 这是一个很好的观点,克里斯,这就是我自己的想法。我检查了单击按钮时生成的请求的 __EVENTTARGET 字段,它具有被单击按钮的 ID。然后我确保我的请求具有相同的 __EVENTTARGET 值,但这似乎没有触发按钮单击事件处理程序。所以也许还有更多。我希望有人可以在这里提供更多的信息.​​.....
    • 我做了一些测试并更新了我的答案。我能够从纯 html 页面发布到 asp.net 页面并触发按钮单击。
    【解决方案6】:

    好的,所以我最后想通了。

    请求应该包含一个名称值对,其中名称是被点击按钮的id,值可以是'1'。

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

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

    【讨论】:

      【解决方案7】:

      祥子,

      ASP.net 回发可能很棘手,但您应该使用 __doPostBack() javascript 函数查看这篇文章以获得一些见解。

      http://www.dotnetspider.com/resources/1521-How-call-Postback-from-Javascript.aspx

      HTH,

      迈克

      【讨论】:

        猜你喜欢
        • 2011-12-27
        • 1970-01-01
        • 2011-04-02
        • 1970-01-01
        • 2018-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多