customerrors = "On" のときに Application_Error が発生しない 質問する

customerrors =

global.asaxファイルのApplication_Errorイベントには、エラーが発生したときに実行され、エラーの詳細を自分に電子メールで送信するコードがあります。

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

    if (error.Message != "Not Found")
    {
        // Send email here...
    }

}

これは Visual Studio で実行しているときは正常に動作しますが、ライブ サーバーに公開するとApplication_Errorイベントは発生しません。

Application_Errorいくつかテストした後、を設定するとイベントが起動できるようになりcustomErrors="Off"ましたが、 に戻すとcustomErrors="On"イベントが再び起動しなくなります。

が有効になっているApplication_Errorのに、なぜ発火しないのか誰か教えてもらえますか?customErrorsweb.config

ベストアンサー1

アップデート
この回答は解決策を提供しているので編集しませんが、この問題を解決するよりクリーンな方法を見つけました。私の他の答え詳細については...

元の回答:
Application_Error()メソッドが呼び出されない理由が分かりました...

グローバル.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute()); // this line is the culprit
    }
...
}

デフォルトでは(新しいプロジェクトが生成されたとき)、MVCアプリケーションにはGlobal.asax.csファイルにロジックがいくつか含まれています。このロジックは、ルートのマッピングとフィルターの登録に使用されます。デフォルトでは、フィルターは1つだけ登録されますHandleErrorAttribute。customErrorsがオンの場合(またはRemoteOnlyに設定されている場合はリモートリクエスト経由)、HandleErrorAttributeはMVCにエラービューを探すように指示し、メソッドは呼び出されませんApplication_Error()。これに関するドキュメントは見つかりませんでしたが、次の説明があります。この回答はprogrammers.stackexchange.comにあります

ApplicationError()メソッドを取得するには未処理の例外の場合は、HandleErrorAttribute フィルターを登録する行を削除するだけです。

ここで問題となるのは、customErrors をどのように構成すれば、必要なものが得られるかということです...

customErrors セクションのデフォルトは ですredirectMode="ResponseRedirect"。defaultRedirect 属性を MVC ルートとして指定することもできます。非常にシンプルな ErrorController を作成し、web.config を次のように変更しました...

ウェブ構成

<customErrors mode="RemoteOnly" redirectMode="ResponseRedirect" defaultRedirect="~/Error">
  <error statusCode="404" redirect="~/Error/PageNotFound" />
</customErrors>

このソリューションの問題点は、エラー URL に 302 リダイレクトを行い、それらのページが 200 ステータス コードで応答することです。これにより、Google がエラー ページをインデックスすることになり、これは好ましくありません。また、HTTP 仕様にあまり準拠していません。私がやりたかったのは、リダイレクトせずに、元の応答をカスタム エラー ビューで上書きすることでした。

変更しようとしましたredirectMode="ResponseRewrite"。残念ながら、このオプションはMVCルートをサポートしていません、静的HTMLページまたはASPXのみ。最初は静的HTMLページを使用しようとしましたが、応答コードは200のままでしたが、少なくともリダイレクトはされませんでした。その後、この答え...

エラー処理には MVC をあきらめることにしました。Error.aspxと を作成しましたPageNotFound.aspx。これらのページは非常にシンプルでしたが、魔法のようなものが 1 つありました...

<script type="text/C#" runat="server">
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        Response.StatusCode = (int) System.Net.HttpStatusCode.InternalServerError;
    }
</script>

このブロックは、正しいステータス コードでページを提供するように指示します。もちろん、PageNotFound.aspx ページでは、HttpStatusCode.NotFound代わりに を使用しました。web.config を次のように変更しました...

<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx">
  <error statusCode="404" redirect="~/PageNotFound.aspx" />
</customErrors>

すべて完璧に機能しました!

まとめ:

  • 次の行を削除します:filters.Add(new HandleErrorAttribute());
  • Application_Error()例外をログに記録するメソッドを使用する
  • ASPXページを指すResponseRewriteでcustomErrorsを使用する
  • ASPXページが独自の応答ステータスコードを管理するようにする

このソリューションにはいくつかの欠点があることに気づきました。

  • ASPX ページは Razor テンプレートとマークアップを共有できないため、一貫した外観と操作性を実現するために、Web サイトの標準ヘッダーとフッターのマークアップを書き直す必要がありました。
  • *.aspxページにはURLを入力することで直接アクセスできます。

これらの問題には回避策がありますが、私はそれほど心配していなかったので、追加の作業はしませんでした。

おすすめ記事