拙稿「.NET TIPS:独自のエラー・ページを設定するには?」でも解説したように、実際のアプリケーションを構築する場合、カスタム・エラー・ページの設置は欠かせない。それはASP.NET MVCの世界でも同様だ。
そこでここでは、カスタム・エラー・ページを設置するためのHandleError属性について紹介する。さっそく、具体的な実装の手順を見ていこう。
[1]アプリケーション構成ファイルを設定する
カスタム・エラー・ページを有効にするには、まずアプリケーション構成ファイルに、カスタム・エラー・ページを設定するための<customErrors>要素を追加する必要がある。
<system.web>
……中略……
<customErrors mode="On" defaultRedirect="Error">
<error statusCode="500" redirect="/ErrorLast.htm" />
</customErrors>
……中略……
</system.web>
<customErrors>要素の詳細については、前述の別稿も参照いただくとして、ここでは特記すべき事項のみ補足しておく。
mode属性には、エラーの表示モードを指定しておく。デフォルトはRemoteOnly(リモート・コンピュータにのみカスタム・エラー・ページを表示)となっているので、開発環境――つまり、ローカル・コンピュータからカスタム・エラーの挙動を確認するには、必ずmode属性はOn(すべての場合にカスタム・エラー・ページを表示)にしておく必要がある。
defaultRedirect属性には、エラー発生時に表示すべきデフォルトのビュー名を指定しておく。これによって、ASP.NET MVCでは以下の順序でビュー・スクリプトを検索する(検索順序については、第3回で紹介したとおりである)。
基本的には、ここまでの設定でもそれなりに動作するが、このままでは若干の問題がある。というのも、カスタム・エラー・ページでエラーが発生した場合には、やはりデフォルトのエラー・ページが表示されてしまうのだ。これを回避するには、リスト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>
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
アクションに対してカスタム・エラー・ページを有効化するのは、冒頭で述べたようにHandleError属性の役割だ。HandleError属性にはさまざまなプロパティが用意されているが、まずは何も指定せずにデフォルトの挙動を確認してみよう。
ブラウザからResult/Dummyアクションを実行し、以下のようなカスタム・エラー・ページが表示されれば、まずは成功である。
Copyright© Digital Advantage Corp. All Rights Reserved.