调用Context.ApplicationInstance.CompleteRequest(Response.Redirect相关)后仍会触发C#ASP.NET事件
尝试按照最佳实践进行响应。重定向调用Context.ApplicationInstance.CompleteRequest(Response.Redirect相关)后仍会触发C#ASP.NET事件,c#,asp.net,redirect,exception,C#,Asp.net,Redirect,Exception,尝试按照最佳实践进行响应。重定向 Response.Redirect(someURl, false); Context.ApplicationInstance.CompleteRequest(); 如本MSDN博客所述: 基本上是说: 使用不会导致线程中止的CompleteRequest重载 例外 的MSDN页面显示: 使ASP.NET绕过HTTP管道中的所有事件和筛选 执行链,并直接执行EndRequest事件 但是,调用CompleteRequest后的所有页面事件仍会触发。因此,不会跳过
Response.Redirect(someURl, false);
Context.ApplicationInstance.CompleteRequest();
如本MSDN博客所述:
基本上是说:
使用不会导致线程中止的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" />
如果选中所有的勾选框,然后按下按钮,会触发许多事件。您似乎认为CompleteRequest()方法将终止页面的执行,类似于Response.Redirect(url,true)。但是,正如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);
}
如果要在选中复选框并单击按钮后进行调试,则复选框将引发回发事件,然后引发渲染,这两个事件都不会被调用。然后将不处理按钮单击事件,并发生重定向
此外,我还发现了与此问题类似的问题,并详细介绍了与CompleteRequest()方法有关的一些信息。在响应中使用false。重定向将结束当前线程的进一步执行。“所以,在某些情况下,它可能会引起问题。”我认为拉维库马尔(Ravikumar)在另一方面说。在Response.Redirect中使用True将结束当前线程的进一步执行,从而引发ThreadAbort异常。这正是我想要避免的。这就是我传递false的原因。您可以共享更多代码或完整的执行线程吗?我不希望它终止执行,我只是希望调用CompleteRequest后不会触发未处理的回发事件,因为MSDN文档暗示会发生这种情况。我的问题是行为与文档不匹配。那篇文章确实提供了一种使用覆盖来引发PostBackEvent和渲染的解决方法。请发布一个答案,包括这部分内容和链接到原来的文章。然后我会将其标记为已接受的答案。“John S Reid”解决方案仅涵盖在页面加载中引发重定向的情况。不幸的是,如果在回发事件中执行重定向,它不会停止所有其他事件的触发。我添加了一个示例,说明如何在checkedchanged事件中重写回发事件/呈现。希望这能让您了解如何在页面加载之外的其他地方进行。另外,这是约翰·S·里德的公司网站,所以这应该是原文。
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);
}