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",但隐藏字段也同样简单。
我遇到了页面重新加载周期的问题,我无法弄清楚。我有一个 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",但隐藏字段也同样简单。