1

我有一组 Asp.Net 应用程序,它们都共享一个通用的 HttpModule,其中包含如下代码:

public class MyModule : IHttpModule
{
    public void Dispose()
    {
    }
    public void Init( HttpApplication context )
    {
        context.Error += new EventHandler( context_Error );
    }
    private void context_Error( object sender, EventArgs e )
    {
        var lastError = HttpContext.Current.Server.GetLastError();
        doSomeStuffWithError(lastError);
        var response = HttpContext.Current.Response;
        var redirect = GetErrorRedirect(lastError);
        response.Redirect(redirect, true);
    }
}

这对我的所有应用程序都很好,除了一个。在无法正常工作的情况下, response.Redirect(...) 似乎不起作用。Asp.Net 不是我期望的重定向,而是重定向到其标准错误页面。我检查了此应用程序的配置,并没有发现任何错误或与其他应用程序有显着差异。

在调查这个问题时,我用另外一行代码修改了错误处理程序,如下所示:

private void context_Error( object sender, EventArgs e )
{
    var lastError = HttpContext.Current.Server.GetLastError();
    doSomeStuffWithError(lastError);
    var response = HttpContext.Current.Response;
    var redirect = GetErrorRedirect(lastError); 
    //setting a break point here, i've verified that 'redirect' has a value in all cases
    response.Redirect(redirect, true);

    var wtf = response.RedirectLocation;
    //inspecting the value of 'wtf' here shows that it is null for one application, but equal to 'redirect' in all others.

}

当我在“wtf”上设置断点时,我看到了一些奇怪的行为。对于有效的应用程序,wtf 包含与重定向相同的值。但是,对于我无法运行的应用程序,wtf 为空。

任何人对什么会导致 wtf 以这种方式为空有任何想法?

4

1 回答 1

1

您正在使用的重载Response.Redirect将调用Response.End并抛出ThreadAbortException. 它在文档中这么说。因此,在其他应用程序中“它有效”这一事实很有趣,因为它不应该var wtf = response.RedirectLocation; 在调试会话期间执行,它为 null 也不足为奇,因为它可能有某种原因允许在调试期间执行该行。

此外,如果您将Web.config 中的设置mode设置为 On 或 RemoteOnly ,它当然会执行默认错误页面,除非您在重定向之前清除错误。这是设计使然。<customErrors>

如果您在调用后需要执行附加代码,请作为第二个参数Response.Redirect传递以避免调用并使用清除错误falseResponse.EndHttpContext.Current.ClearError()

根据您的示例,我会像这样重写您的 HttpModule:

public class MyModule : IHttpModule
{
    public void Dispose()
    {
    }
    public void Init( HttpApplication context )
    {
        context.Error += new EventHandler( context_Error );
    }
    private void context_Error( object sender, EventArgs e )
    {
        var context = HttpContext.Current;
        var lastError = context.Server.GetLastError();

        doSomeStuffWithError(lastError);

        var response = context.Response;
        var redirect = GetErrorRedirect(lastError);

        context.ClearError();

        // pass true if execution must stop here
        response.Redirect(redirect, false);

        // do other stuff here if you pass false in redirect
    }
}
于 2012-09-19T05:54:15.657 回答