1

次のようなコードを含む共通のHttpModuleをすべて共有するAsp.Netアプリケーションのグループがあります。

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);
    }
}

これは、1つを除くすべてのアプリケーションで完全に正常に機能します。正しく動作しない場合は、response.Redirect(...)が動作していないようです。私が期待するリダイレクトの代わりに、Asp.Netは標準のエラーページにリダイレクトしています。このアプリケーションの構成を確認しましたが、他のアプリケーションとの違いや大きな違いは見られません。

この問題を調査しているときに、次のようにもう1行のコードでエラーハンドラーを変更しました。

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はnullです。

誰かがこのようにwtfがnullになる原因について何か考えがありますか?

4

1 に答える 1

1

使用しているのオーバーロードは、Response.Redirectを呼び出しResponse.EndてスローしThreadAbortExceptionます。documentationでそう言っています。したがって、他のアプリケーションで「動作する」という事実は、決して実行されるべきではないため、興味深いものですvar wtf = response.RedirectLocation; 。デバッグ セッション中に、デバッグ中にその行を実行できる何らかの理由がある可能性が高いため、それが null であることも驚くべきことではありません。

さらに、リダイレクトするにエラーをクリアしない限り、Web.configの設定modeを On または RemoteOnly に設定している場合は、もちろん既定のエラー ページが実行されます。これは仕様によるものです。<customErrors>

を既に呼び出した後に追加のコードを実行する必要がある場合は、2 番目のパラメーターとしてResponse.Redirectを渡して呼び出しfalseを回避し、を使用してエラーをクリアしますResponse.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 に答える