web-dev-qa-db-ja.com

ASP.net MVC [HandleError]が例外をキャッチしない

2つの異なるアプリケーションで、1つはカスタム、もう1つは新しいVS2008 MVCプロジェクトで取得するサンプルMVCアプリケーションで、[HandleError]が例外をキャッチしていません。

私が持っているサンプルアプリケーションでは:

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";
        throw new Exception();
        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

これは、デフォルトのコントローラであり、テストのために例外がスローされます。

しかし、それは機能しません。デフォルトのerror.aspxページに移動する代わりに、ブラウザにデバッグ情報を表示します。

問題は、私が取り組んでいるカスタムアプリケーションで最初に発生し、サンプルアプリケーションでテストすることにしました。カスタムアプリケーションで行った変更と関係があると思い、サンプルアプリケーションを完全に変更せずに残しましたが、indexメソッドでのスローの例外はありました。

私は困惑しています。何が欠けていますか?

39
Eric

Web.configで、customErrorsを変更します。

<system.web>
  <customErrors mode="On">
  </customErrors>

モードがOffまたはRemoteOnlyの場合、カスタムエラーページではなく、死の黄色の画面が表示されます。その理由は、開発者は通常、死の黄色の画面でより詳細な情報を求めているということです。

68
Craig Stuntz

重要:エラーページ自体にエラーがないように注意してください。

もしそうなら、あなたはそのASP.NETカスタムエラーページに行き着き、まるで輪になって、あなたの髪を引き裂くでしょう。エラーを引き起こす可能性のあるページからすべてを取り除き、テストします。

また、 'customErrors'がオンまたはオフであることに関して、わかりやすいエラーページ(Errors.aspx)ページが表示されるかどうかには、いくつかの要因があります。

参照 このブログ (以下を除く)

HttpContext.IsCustomErrorEnabled-3つの異なるソースを調べます

  1. Web.configの<deployment>セクションの小売プロパティ。これは、アプリケーションを本番サーバーにデプロイするときに設定する便利なプロパティです。これにより、カスタムエラーの他の設定が上書きされます。
  2. Web.configの<customErrors>セクションのモードプロパティ。この設定は、カスタムエラーを有効にするかどうか、有効にする場合はリモート要求に対してのみ有効にするかどうかを示します。
  3. HttpRequestオブジェクトのIsLocalプロパティ。カスタムエラーがリモート要求に対してのみ有効になっている場合は、要求がリモートコンピューターからのものかどうかを知る必要があります。

ここでの考え方は、開発中に 'customErrors'をオフにすることができるということです。エラーを確認したい場合は、本番環境でのみ有効にできます。

この MSDN記事 は、属性についてさらに説明しています。

16
Simon_Weaver

この問題のもう1つの理由は、

テンプレートMVCアプリケーション(VS2008/VS2008 Expressによって生成)では、Error.aspx(VSによって生成)はマスターページを使用します。

マスターページがいずれかのViewDataにアクセスすると、null参照Exceptionがスローされ、error.aspxは表示されません。

この単純なコードをError.aspxとして使用すると、問題が解決されます(CustomErrors = Onとともに)

<%@ Page Language="C#"  Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %>
<%= Model.Exception.Message %>
13
Palani

私もこれに苦労しており、今では問題を理解していると思います。

つまり、[HandleError]が期待どおりに機能するための要件は次のとおりです。

web.configでカスタムエラーを有効にする必要があり、エラービューが<customErrors>タグのどこにあるかも指定する必要があります。

例:

<customErrors mode="On" defaultRedirect="Error" />

defaultRedirect="Error"の部分を削除すると、代わりにブラウザで500エラーが発生します-ASP.NETエラーページ(YSOD)ではありません。

また、リリースモードである必要はありません。私はデバッグビルドでこれをテストしましたが、うまくいきました。

私の環境は、.NET 4と標準の「ASP.NET MVC 2 Webアプリケーション」プロジェクトテンプレートを使用したVisual Studio 2010でした。

私を混乱させたのは、HandleErrorAttributeクラスのMSDNドキュメントです。 web.configでカスタムエラーをオンにする必要があることを明示的に示していません。そして、必要なのは[Handle Error]属性だけだと思いました。

8
RunnerRick

私と一度起こった愚かな状況があるので、誰かに役立つかもしれません。

追加したことを確認してください<customErrors mode="On" /> to correctweb.configファイル。


ときどき(特に、Resharperなどで作業し、ファイルの名前を入力してソリューションエクスプローラーを介さずにファイルを開く場合)、単にViewsフォルダーまたは別のプロジェクトからでも

5
Agat

注意してください:私の場合、私は HandleError 属性を取得してexceptions内にスローされたControllerをキャッチしようとしていましたコンストラクタ!もちろん、それをキャッチしません。 HandleError属性は、Controlleractions内でスローされた例外のみをキャッチします。それはMSDNページにあります(もっと注意を払うべきでした):

アクションメソッドによってスローされる例外を処理するために使用される属性を表します。

もう1つ起こっていたのは、コントローラーのOnException(ExceptionContext exceptionContext)オーバーライドされたメソッドが呼び出されなかったことです。繰り返しますが、Controllerのコンストラクター内で例外をスローしているため、もちろん呼び出されません。

私はこれを理解するために1時間費やしました。 :o)それが次の魂を助けることを願っています...

ヒントとして:HandleError属性は500エラーのみをキャッチすることに注意してください。他のものについては、_ <customErrors> セクションをWeb.configで宣言する必要があります。

<customErrors mode="On">
  <error statusCode="403" redirect="~/403" />
  <error statusCode="404" redirect="~/404" />
</customErrors>
2