第4回 フィルタ属性による認証/キャッシュ/セキュリティ対策の実装連載:ASP.NET MVC入門(3/5 ページ)

» 2009年08月14日 00時00分 公開

カスタム・エラー・ページを有効化する − HandleError属性 −

 拙稿「.NET TIPS:独自のエラー・ページを設定するには?」でも解説したように、実際のアプリケーションを構築する場合、カスタム・エラー・ページの設置は欠かせない。それはASP.NET MVCの世界でも同様だ。

 そこでここでは、カスタム・エラー・ページを設置するためのHandleError属性について紹介する。さっそく、具体的な実装の手順を見ていこう。

[1]アプリケーション構成ファイルを設定する

 カスタム・エラー・ページを有効にするには、まずアプリケーション構成ファイルに、カスタム・エラー・ページを設定するための<customErrors>要素を追加する必要がある。

<system.web>
  ……中略……

  <customErrors mode="On" defaultRedirect="Error">
    <error statusCode="500" redirect="/ErrorLast.htm" />
  </customErrors>

  ……中略……
</system.web>

リスト8 カスタム・エラー・ページを有効にするためのコード(Web.config)

 <customErrors>要素の詳細については、前述の別稿も参照いただくとして、ここでは特記すべき事項のみ補足しておく。

 mode属性には、エラーの表示モードを指定しておく。デフォルトはRemoteOnly(リモート・コンピュータにのみカスタム・エラー・ページを表示)となっているので、開発環境――つまり、ローカル・コンピュータからカスタム・エラーの挙動を確認するには、必ずmode属性はOn(すべての場合にカスタム・エラー・ページを表示)にしておく必要がある。

 defaultRedirect属性には、エラー発生時に表示すべきデフォルトのビュー名を指定しておく。これによって、ASP.NET MVCでは以下の順序でビュー・スクリプトを検索する(検索順序については、第3回で紹介したとおりである)。

  1. /Views/コントローラ名/ビュー名.aspx
  2. /Views/コントローラ名/ビュー名.ascx
  3. /Views/Shared/ビュー名.aspx
  4. /Views/Shared/ビュー名.ascx

 基本的には、ここまでの設定でもそれなりに動作するが、このままでは若干の問題がある。というのも、カスタム・エラー・ページでエラーが発生した場合には、やはりデフォルトのエラー・ページが表示されてしまうのだ。これを回避するには、リスト8の太字部分(<error>要素)を追加しておくのが好ましい。これによって、カスタム・エラー・ページでサーバ内部エラーが発生した場合にも、最終的に静的なHTMLページ(ErrorLast.htm)が表示されることになる*3

*3 当然であるが、ErrorLast.htmはあらかじめアプリケーション・ルートの直下に用意しておく必要がある。


[2]エラー・ページを用意する

 次に、エラー時に表示すべきビュー・スクリプトを用意する。プロジェクト作成時にすでにデフォルトの/Views/Shared/Error.aspxが用意されているが、これは削除するか、リネームするかして、いったん待避させておくものとする。

 ビュー・スクリプトを作成するには、ソリューション・エクスプローラから「/Views/Shared」フォルダを右クリックし、表示されたコンテキスト・メニューから[追加]−[View]を選択すればよい。もはやおなじみの[Add View]ダイアログが表示されるので、以下の要領で必要な情報を入力する。

項目 設定値
View name Error
Create a partial view(.ascx) チェックしない
Create a strongly-typed view チェックする
View data class HandleErrorInfo
Select master page チェックしない
表3 [Add View]ダイアログの設定値

 [View data class]欄に指定しているHandleErrorInfoクラス(System.Web.Mvc名前空間)は、例外発生時にその詳細情報を保持しているクラスだ。例外発生時にModelプロパティにセットされるので、これをビュー・スクリプトに型付けしておく。

 ビュー・スクリプトの骨組みが生成されたら、次のリスト9の要領でコードを追加する(追記部分は白い文字で表している)。

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >

<head id="Head1" runat="server">
<title>
エラーが発生しました</title>
</head>
<body>
  <div>
    
<ul>
      <li>例外名:
      <%=Html.Encode(Model.Exception.GetType().Name)%></li>
      <li>メッセージ:
      <%=Html.Encode(Model.Exception.Message)%></li>
      <li>発生元:
      <%=Html.Encode(Model.ControllerName)%>/
      <%=Html.Encode(Model.ActionName)%>アクション</li>
    </ul>
  </div>
</body>
</html>

<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage(Of HandleErrorInfo)" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>
エラーが発生しました</title>
</head>
<body>
  <div>

    <ul>
      <li>例外名:
      <%=Html.Encode(Model.Exception.GetType().Name)%></li>
      <li>メッセージ:
      <%=Html.Encode(Model.Exception.Message)%></li>
      <li>発生元:
      <%=Html.Encode(Model.ControllerName)%>/
      <%=Html.Encode(Model.ActionName)%>アクション</li>
    </ul>
  </div>
</body>
</html>

リスト9 カスタム・エラー・ページを定義するビュー・スクリプト(Shared/Error.aspx。上:C#、下:VB)

 HandleErrorInfoクラスには、以下のようなプロパティが用意されている。

プロパティ名 概要
Exception 発生した例外情報
ControllerName 例外発生元のコントローラ名
ActionName 例外発生元のアクション名
表4 HandleErrorInfoクラスの主なプロパティ

 ここではこれらのプロパティ値を直接表示しているが、セキュリティの観点からは、このような内部情報をエンド・ユーザーに公開すべきではない。実際には、例外情報は背後でロギングし、ページ上にはエラーが発生した旨や管理者への連絡先など、必要最低限の情報を表示するにとどめるのが好ましいだろう。

[3]アクション・メソッドを定義する

 最後に、カスタム・エラー・ページを表示するために、あえて例外を発生するテスト用のアクション・メソッドを定義しておこう。

[HandleError()]
public String Dummy() {
  throw new Exception("エラーが発生しました!!");
  return "";
}

<HandleError())> _
Function Dummy() As String
  Throw New Exception("エラーが発生しました!!")
  Return ""
End Function

リスト10 例外を発生するResult/Dummyアクションを定義(上:ResultController.cs、下:ResultController.vb)

 アクションに対してカスタム・エラー・ページを有効化するのは、冒頭で述べたようにHandleError属性の役割だ。HandleError属性にはさまざまなプロパティが用意されているが、まずは何も指定せずにデフォルトの挙動を確認してみよう。

 ブラウザからResult/Dummyアクションを実行し、以下のようなカスタム・エラー・ページが表示されれば、まずは成功である。

図3 Result/Dummyアクションにアクセスした結果
例外が発生し、Error.aspxで定義されたカスタム・エラー・ページが表示された。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。