为什么运行Response.Redirect()时会出现抛出exception?

我正在学习ASP.NET,正在研究QueryStrings。

我正在看的其中一个示例将按钮挂钩到重定向调用:

protected void btnSubmit_Click(object sender, EventArgs e) { try { //throws ThreadAbortException: "Thread was being aborted" Response.Redirect("Form2.aspx"); } catch (Exception Ex) { System.Diagnostics.Debug.WriteLine(Ex.Message); } } 

为什么会在这里抛出ThreadAbortException? 这是正常的吗? 我应该为此做点什么吗? 例外通常不是一件好事,所以当我看到这一点时我感到震惊。

这是设计的。 此知识库文章描述了行为(也适用于Request.End()Server.Transfer()方法)。

对于Response.Redirect() ,存在一个重载:

 Response.Redirect(String url, bool endResponse) 

如果传递endResponse = false ,则不抛出exception(但运行时将继续处理当前请求)。

如果endResponse = true (或者如果使用不带bool参数的重载),则抛出exception并立即终止当前请求。

这个是正常的。 Server.Transfer()也会抛出相同的exception。

这是因为在内部,两个方法都调用Response.End() ,它立即中止当前请求处理。 Rick Strahl有一篇非常好的博客文章 ,分析了为什么你几乎没有办法避免这些例外。

Response.Redirect在内部调用Response.End,因此抛出exception,改为使用:

 Response.Redirect(url, false); 

这是正常的,因为这是意味着发生的事情。 基本上,当响应设置为重定向时,ASP.NET期望您完全完成请求。 它会中止线程,以防止发生任何其他处理(基本上它会为您调用Response.End ,并抛出exception)。

在我看来,它有点滥用exception,但这就是它的工作方式。 您可以使用具有第二个参数(并传递false )的重载来防止这种情况发生 – 如果您愿意 – 但如果是这样,请确保没有其他任何内容然后尝试写入响应!

我相信你需要遵循这篇知识库文章中的说明。 Response.Redirect调用Response.End(),除非您使用专门用于避免此行为的重载。 一旦响应结束,就不会发生进一步的操作,因此TA exc。

http://support.microsoft.com/kb/312629

该行为是为了支持旧的asp。 以下是MS描述您正在体验的内容的链接。

http://support.microsoft.com/default.aspx?scid=kb;EN-US;312629

调用只接受URL的Redirect()的重载也会导致调用Response.End() – 它会抛出ThreadAbortexception,以确保在页面/ UC中重定向之后没有其他代码运行。

您不应该捕获此exception..您应该在代码中忽略它或使用Redirect()的重载,它接受一个布尔值,指示在重定向后是否继续处理请求。

是啊。 我在那之后编写了一个退出子,但我知道它没有到达。

我想如果你想要你可以吃掉这个例外并继续进行更多的事情,但我不会推荐它。

这里已经有了一堆合理的答案。 还有一点值得注意。 线程中止exception是您可以捕获和编码的罕见exception之一,但您无法抑制。 无论你做什么,它都会在任何try / catch / finally块结束时自动重新引发。

如果你决定忍受这个例外,你应该确保你的健康监测允许这个并且不报告它作为一个问题,所以你不要被困在一群试图解释的非技术经理面前为什么你的网站会抛出如此多的线程中止例外。 (我让一位经理确信所有这些线程堕胎都背后一团糟,当然这与线程中止的意图完全相反。)