当我使用Response.Redirect(...)将表单重定向到新页面时,我收到错误:
mscorlib.dll中出现'System.Threading.ThreadAbortException'类型的第一次机会异常mscorlib.dll中发生类型为'System.Threading.ThreadAbortException'的异常,但未在用户代码中处理
我对此的理解是,错误是由Web服务器中止调用response.redirect的页面的其余部分引起的 .
我知道我可以在 Response.Redirect
中添加第二个参数,称为endResponse . 如果我将endResponse设置为True,我仍然会收到错误,但如果我将其设置为False,那么我不会 . 我很确定,这意味着网络服务器正在运行我重定向的页面的其余部分 . 至少可以说这似乎效率低下 . 有一个更好的方法吗? Response.Redirect
以外的东西还是有办法强制旧页面停止加载我不会得到 ThreadAbortException
?
10 回答
正确的模式是使用endResponse = false调用Redirect重载并调用告诉IIS管道,一旦返回控件,它应该直接前进到EndRequest阶段:
Thomas Marquardt的This blog post提供了其他详细信息,包括如何处理Application_Error处理程序内部重定向的特殊情况 .
ASP.Net WebForms中的
Redirect
问题有 no 简单而优雅的解决方案 . 您可以在 Dirty 解决方案和 Tedious 解决方案之间进行选择Dirty :
Response.Redirect(url)
向浏览器发送重定向,然后抛出ThreadAbortedException
以终止当前线程 . 因此,没有代码执行Redirect() - 调用 . 缺点:这是一种不好的做法,并且会对杀死这样的线程产生影响 . 此外,ThreadAbortedExceptions
将显示在异常日志记录中 .Tedious :建议的方法是调用
Response.Redirect(url, false)
然后调用Context.ApplicationInstance.CompleteRequest()
但是,代码执行将继续,页面生命周期中的其余事件处理程序仍将执行 . (例如,如果您在Page_Load中执行重定向,则不仅会执行处理程序的其余部分,还会调用Page_PreRender等等 - 渲染的页面将不会被发送到浏览器 . 您可以避免额外的处理例如,在页面上设置一个标志,然后让后续事件处理程序在进行任何处理之前检查此标志 .(
CompleteRequest
的文档声明它“导致ASP.NET绕过所有事件并在HTTP管道执行链中进行过滤” . 这很容易被误解 . 它确实绕过了进一步的HTTP过滤器和模块,但它没有进一步绕过当前页面生命周期中的事件 . )更深层次的问题是WebForms缺乏抽象层次 . 当您在事件处理程序中时,您已经在构建要输出的页面的过程中 . 在事件处理程序中重定向很难看,因为您要终止部分生成的页面以生成不同的页面 . MVC没有这个问题,因为控制流与渲染视图是分开的,所以你可以通过简单地在控制器中返回
RedirectAction
而不生成视图来进行干净的重定向 .我知道如果我的
Response.Redirect
在Try...Catch
块中,我只会遇到此错误 .永远不要将Response.Redirect放入Try ... Catch块 . 这是不好的做法
编辑
为了回应@Kiquenet的评论,我将做的是将Response.Redirect放入Try ... Catch块的替代方案 .
我将方法/功能分解为两个步骤 .
Try ... Catch块中的第一步执行请求的操作并设置“结果”值以指示操作的成功或失败 .
Try ... Catch块之外的第二步是重定向(或不重定向),具体取决于“结果”值是什么 .
这段代码远非完美,可能不应该复制,因为我还没有测试过
Response.Redirect()
抛出异常以中止当前请求 .这KB article描述了这种行为(也适用于
Request.End()
和Server.Transfer()
方法) .对于
Response.Redirect()
,存在过载:如果传递 endResponse=false ,则不会抛出异常(但运行时将继续处理当前请求) .
如果 endResponse=true (或者如果使用了其他重载),则抛出异常并立即终止当前请求 .
这是只是Response.Redirect(url,true)如何工作 . 它抛出ThreadAbortException以中止线程 . 只是忽略那个例外 . (我认为它是一个全局错误处理程序/ Logger ,你在哪里看到它?)
一个有趣的相关讨论Is Response.End() considered harmful?
这是关于问题的official line(我不能认为.net的更高版本的情况已经发生了变化)
我甚至试图避免这种情况,以防万一在线程上手动执行Abort,但我宁愿将其保留为“CompleteRequest”并继续前进 - 我的代码在重定向后仍返回命令 . 所以这可以做到
我也尝试了其他解决方案,但重定向后执行了一些代码 .
因此,如果需要在重定向后阻止代码执行
我所做的是捕获此异常,以及另一个可能的例外 . 希望这能有所帮助 .
我也有这个问题 . 尝试使用Server.Transfer而不是Response.Redirect为我工作