HandleErrorフィルタ
ASP.NET 1.Xの時から、既定のエラー画面が表示されてもユーザーは何が起こっているのかよく理解ができません。HandleErrorフィルタは、開発者だけでなく、ページを利用するユーザーすべてに、エラーの発生を分かりやすく表示させます(図2参照)。
HandleErrorフィルタは、すべての例外に対しプロジェクト作成時に作成される「\Views\Shared」フォルダに格納されている「Error.aspx」を介してエラーを表示します。
HandleErrorフィルタを利用するには、web.configのSystem.Webセクション内に以下を記述します。作成直後はコメントアウトされているので、コメントインしてから太字部分を編集してください。
<customErrors mode="On" defaultRedirect="Error">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
customErrorsセクションでHandleErrorフィルタを利用する事を設定し(mode="On")、エラーが発生した場合のリダイレクト先を"Error.aspx"へと設定します(defaultRedirect="Error")。customErrorsセクション内では、具体的にHTTPリクエストエラー(statusCode="403"など)が発生した場合のリダイレクト先を設定しています(redirect="NoAccess.htm")。これらは既定で用意されていないので、開発者が対応ページを作成し配置します。
Error.aspxの中身はどう設定する?
さて、ここで気になるのはError.aspxファイルの中身だと思います。作成直後のError.aspxページは、エラーを表示する英文が書いてあるだけで例外情報を表示させるコードは書かれていません。ではどのように例外情報を取得すればよいでしょうか? MSDNにお手本のコードが書かれていたので流用させていただきます(英語→日本語に変換はしています)。
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %>
<!-- <中略> -->
<h2>
すみません、あなたのリクエスト処理中にエラーが発生してしまいました。
</h2>
<h2>エラー詳細</h2>
<p>
<b>どこのControllerで発生しました?: </b><%=Model.ControllerName %>
</p>
<p>
<b>どこのActionで発生しました?: </b><%=Model.ActionName %>
</p>
<p>
<b>どんなMessageを持っていますか?: </b><%=Model.Exception.Message %>
</p>
<p>
<b>Stack Traceは次の通りです。: </b><%=Model.Exception.StackTrace %>
</p>
上記コードのポイントは2つあります。1つはViewDataです。@Pageディレクティヴでエラー情報をカプセル化しているHandleErrorInfoクラス(後述)を型付きViewとして定義しています。コンテンツ部分では、ViewDataのModelプロパティを利用して、エラー表示の際の例外情報を表示します。エラー表示に関するキーは次の3つです。
| プロパティ名 | 概要 |
| ActionName | 例外が発生時のAction名を取得 |
| ControllerName | 例外が発生時のController名を取得 |
| Exception | 例外オブジェクトの取得 |
Exceptionプロパティは例外オブジェクトなので、MessageプロパティやStackTraceプロパティが利用できます。
もう1つはHandleErrorInfoクラスです。HandleErrorInfoクラスはActionMethodによってスローされたエラーハンドリング情報をカプセル化します。つまり、上記コードでは、ViewData.Modelのエラーハンドリング情報をカプセル化し、例外発生箇所と例外メッセージ、スタックトレースを取得しています。
エラーによる表示ページの変更
エラーにより表示したいページを切り替えたいときは、HandleErrorフィルタのパラメタを次のように設定します(図3~図4)。
[HandleError(Order = 1)]
[HandleError(ExceptionType = typeof(DataException), View = "DataError")]
[HandleError(
ExceptionType = typeof(NullReferenceException), View = "NullError")]
public class PubsController : Controller
{
// <中略>
public object NullEx()
{
throw new NullReferenceException();
}
public object DataEx()
{
throw new DataException( );
}
}
ExceptionTypeプロパティに例外の型を、Viewプロパティに表示するViewPageを設定します。上記のように設定している場合、SqlException・HttpExceptionは専用のページ(NullError.aspx、HttpError.aspx)を表示し、その他の例外は既定のエラーページが表示されます。何も設定しなければ宣言した順番で優先的にフィルタが適用されますが、Orderプロパティを1以上に設定すると優先順位が下がります(複数個宣言してHandleErrorを最後に適用したいのであれば、複数個分の数値を設定)。



