当我使用Response.Redirect(…)将我的表单重定向到一个新页面时,我得到了错误:

类型为'System.Threading '的第一次机会异常。mscorlib.dll中出现ThreadAbortException ` System.Threading类型的异常。在mscorlib.dll中出现ThreadAbortException',但在用户代码中没有处理

我对此的理解是,该错误是由web服务器中止余下的页面响应引起的。重定向被调用。

I know I can add a second parameter to Response.Redirect that is called endResponse. If I set endResponse to True I still get the error but if I set it to False then I do not. I am pretty sure though that that means the webserver is running the rest of the page I redirected away from. Which would seem to be inefficient to say the least. Is there a better way to do this? Something other than Response.Redirect or is there a way to force the old page to stop loading where I will not get a ThreadAbortException?


当前回答

我甚至试图避免这一点,以防万一在线程上手动做中止,但我宁愿留下它与“CompleteRequest”和继续-我的代码有返回命令后重定向无论如何。这是可以做到的

public static void Redirect(string VPathRedirect, global::System.Web.UI.Page Sender)
{
    Sender.Response.Redirect(VPathRedirect, false);
    global::System.Web.UI.HttpContext.Current.ApplicationInstance.CompleteRequest();
}

其他回答

下面是关于这个问题的官方说法(我找不到最新的,但我认为。net的后续版本情况没有改变)

对于ASP中的重定向问题,没有简单而优雅的解决方案。净WebForms。您可以在肮脏的解决方案和乏味的解决方案之间进行选择

Response.Redirect(url)发送一个重定向到浏览器,然后抛出一个ThreadAbortedException来终止当前线程。因此,在Redirect()调用之后不会执行任何代码。缺点:像这样杀死线程是一种糟糕的做法,会影响性能。此外,ThreadAbortedExceptions将显示在异常日志记录中。

Tedious: The recommended way is to call Response.Redirect(url, false) and then Context.ApplicationInstance.CompleteRequest() However, code execution will continue and the rest of the event handlers in the page lifecycle will still be executed. (E.g. if you perform the redirect in Page_Load, not only will the rest of the handler be executed, Page_PreRender and so on will also still be called - the rendered page will just not be sent to the browser. You can avoid the extra processing by e.g. setting a flag on the page, and then let subsequent event handlers check this flag before before doing any processing.

(CompleteRequest的文档声明它“导致ASP。NET可以绕过HTTP管道执行链中的所有事件和过滤”。这很容易被误解。它会绕过进一步的HTTP过滤器和模块,但不会绕过当前页面生命周期中的进一步事件。)

更深层次的问题是WebForms缺乏抽象级别。当您处于事件处理程序中时,您已经处于构建要输出的页面的过程中。在事件处理程序中重定向是丑陋的,因为您要终止部分生成的页面以生成不同的页面。MVC没有这个问题,因为控制流与呈现视图是分开的,所以你可以通过简单地在控制器中返回一个RedirectAction来做一个干净的重定向,而不生成视图。

我甚至试图避免这一点,以防万一在线程上手动做中止,但我宁愿留下它与“CompleteRequest”和继续-我的代码有返回命令后重定向无论如何。这是可以做到的

public static void Redirect(string VPathRedirect, global::System.Web.UI.Page Sender)
{
    Sender.Response.Redirect(VPathRedirect, false);
    global::System.Web.UI.HttpContext.Current.ApplicationInstance.CompleteRequest();
}

正确的模式是使用endResponse=false调用重定向重载,并调用IIS管道,一旦你返回控制,它应该直接进入EndRequest阶段:

Response.Redirect(url, false);
Context.ApplicationInstance.CompleteRequest();

Thomas Marquardt的这篇博客文章提供了更多的细节,包括如何处理Application_Error处理程序内部重定向的特殊情况。

我也尝试了其他解决方案,但一些代码执行后重定向。

public static void ResponseRedirect(HttpResponse iResponse, string iUrl)
    {
        ResponseRedirect(iResponse, iUrl, HttpContext.Current);
    }

    public static void ResponseRedirect(HttpResponse iResponse, string iUrl, HttpContext iContext)
    {
        iResponse.Redirect(iUrl, false);

        iContext.ApplicationInstance.CompleteRequest();

        iResponse.BufferOutput = true;
        iResponse.Flush();
        iResponse.Close();
    }

所以如果需要防止代码执行后重定向

try
{
   //other code
   Response.Redirect("")
  // code not to be executed
}
catch(ThreadAbortException){}//do there id nothing here
catch(Exception ex)
{
  //Logging
}