1. ホーム
  2. asp.net-mvc-3

[解決済み] customerrors = "On "の場合、アプリケーションエラーが発生しない。

2022-07-28 19:24:48

質問

私は 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 が実行されないのはなぜでしょうか? customErrors が有効な場合 web.config ?

どのように解決するのですか?

アップデイト

この回答は解決策を提供しているので、私はそれを編集しませんが、私はこの問題を解決するためのよりクリーンな方法を見つけました。以下を参照してください。 私の他の回答 をご覧ください...

オリジナルの回答です。

私はなぜ 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をこのように変更しました...

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.aspxPageNotFound.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 を叩くことで直接アクセスすることができます。

これらの問題には回避策がありますが、私は余分な作業をするほど気にしていませんでした。

皆さんのお役に立てれば幸いです。