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
ベストアンサー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を入力することで直接アクセスできます。
これらの問題には回避策がありますが、私はそれほど心配していなかったので、追加の作業はしませんでした。