尝试遵循Response.Redirect的最佳做法
Response.Redirect(someURl, false);
Context.ApplicationInstance.CompleteRequest();
如本MSDN博客中所述:correct-use-of-system-web-httpresponse-redirect 基本上说:
使用不会导致线程中止的CompleteRequest重载 异常。
CompleteRequest的MSDN页面说:
使ASP.NET绕过HTTP管道中的所有事件和过滤 执行链并直接执行EndRequest事件。
但是,调用CompleteRequest后的所有页面事件仍然会触发。因此不会跳过任何代码。这似乎与MSDN文档相矛盾。有解决方法吗?我误解了文档吗?
(博客文章确实说跳过是在页面级别,但API文档没有说明这一点。我猜测答案只是文档有误导性。)
您可以通过调试步进测试非常简单的页面:
<asp:CheckBox ID="CheckBox0" runat="server" OnCheckedChanged="chk_CheckedChanged" />
<asp:CheckBox ID="CheckBox1" runat="server" OnCheckedChanged="chk_CheckedChanged" />
<asp:CheckBox ID="CheckBox2" runat="server" OnCheckedChanged="chk_CheckedChanged" />
<asp:CheckBox ID="CheckBox3" runat="server" OnCheckedChanged="chk_CheckedChanged" />
<asp:Button ID="btnRedirect" runat="server" Text="Click Me" OnClick="btnRedirect_Click" />
<asp:Label ID="lblNotes" runat="server" />
代码:
protected void Page_Load(object sender, EventArgs e)
{
lblNotes.Text += " Load " + DateTime.Now.ToString();
}
protected void Page_PreRender(object sender, EventArgs e)
{
lblNotes.Text += " PreRender " + DateTime.Now.ToString();
}
protected void chk_CheckedChanged(object sender, EventArgs e)
{
Response.Redirect("stackoverflow.com", false);
Context.ApplicationInstance.CompleteRequest();
}
protected void btnRedirect_Click(object sender, EventArgs e)
{
lblNotes.Text += " Btn " + DateTime.Now.ToString();
}
如果勾选所有勾选框,则按下按钮会触发许多事件。
答案 0 :(得分:0)
您似乎认为CompleteRequest()方法将终止类似于Response.Redirect(url, true )的页面执行。但是,正如this article中的John S Reid所解释的那样,CompleteRequest将仅结束ASP.NET应用程序生命周期中页面执行步骤之后发生的应用程序事件,这可能会根据ASP.NET的版本而更改
该页面仍将处理回发事件并呈现页面,但上面的文章中有一个示例,说明如果您对一个示例感兴趣可以防止这种情况。
以下是您的示例的代码:
private m_bIsTerminating = false;
protected void chk_CheckedChanged(object sender, EventArgs e)
{
Response.Redirect("Default2.aspx", false);
Context.ApplicationInstance.CompleteRequest();
m_bIsTerminating = true;
}
protected void btnRedirect_Click(object sender, EventArgs e)
{
lblNotes.Text = "button click event";
}
protected override void RaisePostBackEvent(IPostBackEventHandler
sourceControl, string eventArgument)
{
if (m_bIsTerminating == false)
base.RaisePostBackEvent(sourceControl, eventArgument);
}
protected override void Render(HtmlTextWriter writer)
{
if (m_bIsTerminating == false)
base.Render(writer);
}
如果您在检查框并单击按钮后进行调试,则复选框将引发回发事件,然后呈现渲染,两者都不会被调用。然后,不会处理按钮单击事件,并且会发生重定向。
另外,我发现这个stackoverflow post与此问题类似,并且有关于CompleteRequest()方法的更多信息。