1

MVC 3 プロジェクトの global.asax 内ですべてのアプリケーション例外を処理しようとしています。Cassini 内ではすべてが正しく機能していますが、IIS 7.5 にデプロイするとすぐに、IIS がアプリケーションから制御を奪い始め、多くの例外自体を処理します。これにより、カスタム ロギングがバイパスされ、醜いビューが返されます。

この質問に対するダーリンの回答にも同様のアプローチがあります。これが私が現時点で使用しているものです。

protected void Application_Error(object sender, EventArgs e)
{
    var app = (MvcApplication)sender;
    var context = app.Context;
    var exception = app.Server.GetLastError();

    LogExceptionDetails(exception, Request.Url.PathAndQuery);

    context.Response.Clear();
    context.ClearError();

    string redirectTo = "/error";
    HttpException httpException = exception as HttpException;

    if (httpException != null)
    {
        switch (httpException.GetHttpCode())
        {
            case 403:
                redirectTo += "/forbidden";
                break;
            case 404:
                redirectTo += "/notfound";
                break;
        }
    }

    Response.TrySkipIisCustomErrors = true;

    // I should really change this so I can return a proper statusCode
    Response.Redirect(redirectTo);
}

例として、に移動するlocalhost/app_codeと見苦しいビューが返され、ログに記録されません。以下を使用して、少なくともIISがカスタムビューを返すようにすることができました。

<httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="403" />
    <error statusCode="403" path="/error/forbidden" responseMode="ExecuteURL" />
    <remove statusCode="404" />
    <error statusCode="404" path="/error/notfound" responseMode="ExecuteURL" />
</httpErrors>

ただし、ログの問題は解決しません。

私が試した他のことは次のとおりです。

  1. 設定existingResponse="PassThrough"
  2. を使用し<clear />ます。
  3. httpErrorsありとなしのさまざまな組み合わせcustomErrors
  4. 設定<modules runAllManagedModulesForAllRequests="true" />
  5. Response.TrySkipIisCustomErrors = true;

これをプログラムで処理する方法はありますか?

4

1 に答える 1

1

はい。これが私がやっていることですが、残念ながら完璧ではありません。

まず、カスタム エラーをオフにします。

<customErrors mode="Off" />

次に、HttpErrors を Detailed に変更します。これは私が特に好きではない部分であることに注意してください。主にこれを行うと、スタック トレースにアクセスできるようになる可能性があるためです。キャッチオールを使用して、エラー処理ですべてのステータス コードを処理する限り、問題はないと思います。間違っている場合は修正してください。

<httpErrors errorMode="Detailed" />

catch all route定義したルートと一致しないすべての MVC ルートをキャッチして 404 に送信するには、global.asax にも が必要です。主に、キャッチに依存している場合、これはルートの設定によっては問題になる可能性があります。 all route を使用して、現在の非 404 ルートを処理します。リフレクションを使用して、コントローラーのアクション メソッドに基づいてすべてのルートを定義しているため、アプリケーションのルートのすべてをキャッチするパターンに依存していません。

最後に、global.asax でエラーを処理します。キャッチオール (500 など) を使用し、404 エラーなど、別のものが必要な場合は特別なルーティングを行います。

protected void Application_Error(object sender, EventArgs e)
{
    var ex = Server.GetLastError().GetBaseException();

    Server.ClearError();

    var routeData = new RouteData();
    routeData.Values.Add("controller", "Error");
    routeData.Values.Add("action", "500");

    if (ex.GetType() == typeof (HttpException))
    {
        var httpException = (HttpException) ex;
        var code = httpException.GetHttpCode();

        // Is it a 4xx Error
        if (code % 400 < 100)
        {
            routeData.Values["action"] = "404";
        }
    }

    IController errorController = new ErrorController();
    errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}

この例では、4xx エラーを除くすべてのエラーを 500 として扱います。また、この例では、"ErrorController" という名前のコントローラーと、"500" および "404" という名前の 2 つのアクションを使用しています。

これがお役に立てば幸いです。「詳細」に設定する必要がある HttpErrors の回避策を見つけた場合は、共有してください。

于 2012-08-19T06:46:20.013 に答える