ASP 按钮的生命周期是多少?

What is the life cycle of an ASP button?

我遇到了页面重新加载周期的问题,我无法弄清楚。我有一个 ASP 按钮在服务器上运行,但它有一个关联的客户端点击。客户端 Javascript 正确地 运行 并返回 true 到按钮点击所以它也是 运行。 Javascript 对 URL 上的查询字符串进行了修改,这也有效。但是,在后面的 C# 代码中,查询字符串不存在。在某处,我遗漏了一些东西。

HTML link:

<asp:Button ID="btnRunMOReport" class="button-dbg" runat="server" 
     Text="Run MO Report" OnClick="btnMO_Report_Click" 
     OnClientClick="return validateCheckBoxesMO()" />

JavaScript部分:

function validateCheckBoxesMO() {
   token='xyz';
   let url1 = window.location.href;

   if (url1.indexOf("?") > 0) {
     url1 = url1.substring(0, url.indexOf("?"));
   }

   url1 += "?hiddenToken=" + token;
   window.location.replace(url1);

   return true;
}

hiddenToken 现在显示在页面上 (?hiddenToken=xyz)。

后面的代码:

protected void btnMO_Report_Click(object sender, EventArgs e)
{
    MailMessage mailtest = new MailMessage();
    mailtest.IsBodyHtml = true;

    SmtpClient SmtpServertest = new SmtpClient(ConfigurationManager.AppSettings["smtp_server"]);

    mailtest.To.Add("Whoever@test123.com");
    mailtest.From = new MailAddress("Whoever@test123.com");
    mailtest.Subject = Request.QueryString["hiddenToken"];
    mailtest.Body = "Whatever";
}

邮件很好,但主题是空白。不知何故,在页面重新加载周期期间,尚未设置查询字符串。

如果有更好的方法将数据从 JavaScript 传递到后面的代码,我会洗耳恭听。

我想从后面的代码启动另一个页面,但我需要一些从 JS 返回的数据。该令牌实际上是我获取、处理 JSON 的东西,现在我想让该令牌可用于后面的代码,以获取附加信息以添加到我正在构建的新 URL 中。这可能是 TMI,但这是我正在尝试做的。

感谢您的帮助。

  • 您的脚本无法正常工作,因为浏览器使用 <form>action="" 属性发出 POST 提交表单(和 __VIEWSTATE)的请求WebForms 添加到您的页面。
  • 当您的客户端脚本设置 window.location 时,它不会改变 <form> 的行为方式。您可以使用您的脚本将新的查询字符串值附加到 <form>action="" 属性,并且此 可能 有效,但是如果应用程序有启用请求验证(在这种情况下 ASP.NET 将拒绝 篡改的 表单提交)。

因为您正在使用 WebForms (并且您不应该在 2021 年使用 WebForms...) 除非您了解这一切,否则您不应该尝试与之抗争有效(我并不是想居高临下:我花了 才弄明白这一切,我从 2004 年开始就一直在使用 WebForms)。

Instead, provide the value through an <asp:HiddenField>:

将您的 .aspx 标记更改为:

<asp:Button runat="server" ID="btnRunMOReport" class="button-dbg" 
     Text="Run MO Report" OnClick="btnMO_Report_Click" 
     OnClientClick="return validateCheckBoxesMO()" />

<asp:HiddenField runat="server" ID="superSecretHiddenField"  />

将您的客户端脚本更改为:

function validateCheckBoxesMO() {
    const hiddenFieldId = '<%= this.superSecretHiddenField.ClientID %>';
    const hiddenField   = document.getElementById( hiddenFieldId );

    token='xyz';
   
    hiddenField.value = token;

    return true; // <-- This is wrong, btw. Instead use `Event.prototype.stopPropagation()` - but that requires the on-click function to be wired-up correctly and I don't remember the specifics other than that WebForms *doesn't* do things correctly (not out-of-spite, but because WebForms predates the standardisation of client-script events).
}

还有你的隐藏代码:

protected void btnMO_Report_Click(object sender, EventArgs e)
{
    MailMessage mailtest = new MailMessage();
    mailtest.IsBodyHtml = true;

    SmtpClient SmtpServertest = new SmtpClient(ConfigurationManager.AppSettings["smtp_server"]);

    mailtest.To.Add("Whoever@test123.com");
    mailtest.From = new MailAddress("Whoever@test123.com");
    mailtest.Subject = this.superSecretHiddenField.Value;
    mailtest.Body = "Whatever";
}

如前所述,post 返回按钮通常会覆盖您更改的 url。除非你真的做了一个由js引起的导航客户端,否则它不会持久化。

因此,在最简单的层面上,只需放入一个文本框或隐藏字段,然后将您 need/want 的值放入该隐藏文本框或字段中。

那么,客户端?标记?

你可以使用这个:

        <asp:Button ID="Button1" runat="server" Text="Delete"
            OnClientClick="SetHidden();"/>

        <asp:HiddenField ID="HiddenField1" runat="server" ClientIDMode="Static"/>

        <br />
        <script>
            function SetHidden() {
                hField = document.getElementById('HiddenField1');
                hField.value = 'zoo';
                return true;
            }
        </script>

所以在上面,我们将我们在js中的值设置为zoo,当然我们这样做return true。如果我们 return false 那么 asp.net 按钮代码服务器端将不会 运行 - 所以我们可以控制它,甚至说弹出一个确认对话框和 return true/false 基于此来控制后面的服务器端代码是否会 运行.

服务器端,代码隐藏?您现在可以使用这个:

Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Debug.Print(HiddenField1.Value)

End Sub

以上内容简单明了。您也可以使用文本框,并设置 style="display:none",但隐藏字段也同样简单。