連載:VS 2005でいってみようDBプログラミング

第11回 実践アプリケーションでもっと踏み込むASP.NET 2.0の世界

山田 祥寛(http://www.wings.msn.to/
2006/12/23
Page1 Page2 Page3 Page4

アプリケーション・エラーに関する情報を管理者にメールで通知する

 最後に、掲示板アプリケーションで例外が発生した場合に、その詳細情報(図10)をアプリケーション管理者にメールで通知するための機能を実装してみましょう。


図10 例外発生時に管理者に送信されるメールのメッセージ例

 また、この場合には、エンドユーザーにはカスタムのエラー・ページを表示します(図11)。


図11 例外発生時にエンドユーザーに表示されるカスタム・エラー・ぺージ

[1]Global.asaxを新規作成する

 Global.asaxは、アプリケーション・レベル(アプリケーション全体)で発生する各種イベントを処理するためのファイルです。「グローバル・アプリケーション・クラス」と呼ばれる場合もあります。

 Global.asaxを利用することで、アプリケーション/セッション共通のリソースを定義したり、アクセス・ログや(本稿で紹介するような)例外情報の処理、独自の認証機能などを実装したりすることが可能になります。

 Global.asaxを作成するには、ソリューション・エクスプローラでアプリケーション・ルートを右クリックし、表示されたコンテキスト・メニューから[新しい項目の追加]を選択します。[新しい項目の追加]ダイアログが表示されますので、必要な情報を表8の要領で入力/選択したうえで[追加]ボタンをクリックします。

項目 入力値
テンプレート グローバル・アプリケーション・クラス
名前 Global.asax
言語 Visual Basic
表8 Global.asax追加時の[新しい項目の追加]ダイアログの入力項目

 アプリケーション構成ファイル(Web.config)とは異なり、Global.asaxは必ずアプリケーション・ルート「直下」に配置する必要がある点に注意してください。また、ファイル名も「Global.asax」で固定です。

[2]イベント・ハンドラを記述する

 コード・エディタ上ではGlobal.asaxの骨組みが表示され、すでにいくつかのイベント・ハンドラの骨組みが自動生成されていることが確認できるはずです。

 Global.asaxで利用可能なイベントは17個にも及び、特定の条件下でのみ発生する「条件付きイベント」とリクエスト時に常に発生する「リクエスト・イベント」に大別できます。表9に、Global.asaxで利用可能なイベント・ハンドラをまとめておくことにしましょう。

分類 イベント・ハンドラ 呼び出しのタイミング
リクエスト・イベント Application_OnBeginRequest リクエスト処理を開始する前
Application_OnAuthenticateRequest 認証の直前
Application_OnAuthorizeRequest 認証が完了したタイミング
Application_OnResolveRequestCache リクエストをキャッシングするタイミング
Application_OnAcquireRequestState セッション状態などを取得するタイミング
Application_OnPreRequestHandlerExecute ページの実行を開始する直前
Application_OnPostRequestHandlerExecute ページの実行を完了した直後
Application_OnReleaseRequestState すべての処理を完了したタイミング
Application_OnUpdateRequestCache 出力キャッシュを更新したタイミング
Application_OnEndRequest すべてのリクエスト処理が完了したタイミング
Application_OnPreSendRequestHeaders ヘッダをクライアントに送信する直前
Application_OnPreSendRequestContent コンテンツをクライアントに送信する直前
条件付きイベント Application_OnStart アプリケーションが初回起動したタイミング
Session_OnStart ユーザー・セッションが初回起動したタイミング
Session_OnEnd ユーザー・セッションがクローズするタイミング
Application_OnEnd アプリケーションがクローズするタイミング
Application_OnError アプリケーションで処理されない例外が発生したタイミング
表9 Global.asaxで定義可能なイベント・ハンドラ

 ここでは、Application_OnErrorイベント・ハンドラを実装することで、アプリケーション内で発生した例外を処理します。具体的なコードはリスト6のとおりです。

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)

  Dim Context As HttpContext = _
    DirectCast(sender, HttpApplication).Context

   ' 最後に発生した例外情報を取得
  Dim err As Exception = _
    Context.Server.GetLastError().InnerException

  If err IsNot Nothing Then

    ' 例外情報からメール本文を生成
    Dim builder As New StringBuilder()
    builder.Append(Context.Request.RawUrl) ' リクエストURL
    builder.Append(Chr(13) & Chr(10))
    builder.Append(err.Message) ' 例外メッセージ
    builder.Append(Chr(13) & Chr(10))

    ' 送信メールに関する情報を定義
    Dim mail As New MailMessage()
    mail.To.Add(New MailAddress("CQW15204@nifty.com"))
    mail.Subject = _
      String.Format("エラー発生({0})", _
      DateTime.Now.ToString())
    mail.Body = builder.ToString()

    ' 定義済みのメールメッセージを送信
    Dim smtp As New SmtpClient()
    smtp.Send(mail)
  End If
End Sub
リスト6 アプリケーション・エラー発生時に実行するコード(Global.asax)

 コードの大まかな流れは、プログラム内のコメントを参照いただくとして、ここで注目していただきたいポイントは、以下の2点です。

(1)例外情報を取得するのはGetLastErrorメソッドの役割

 Server.GetLastErrorメソッドは、アプリケーション内で発生した直近の例外情報をExceptionオブジェクトとして返します。ここでは、そのInnerExceptionプロパティを取得することで、現在の例外発生の原因となったExceptionオブジェクトを取得しています。

 アプリケーション・レベルでServer.GetLastErrorメソッドが返す例外はHttpUnhandledException例外(HTTPリクエストの処理中に発生した一般例外)にすぎず、これでは例外発生の原因を特定できません。必ずInnerExceptionプロパティで、もう一段前のExceptionオブジェクトを取得する必要がある点に注意してください。

 Exception.Messageプロパティは例外に関する詳細メッセージを表します。ここでは例外メッセージと例外が発生したページの情報を改行(Chr(13) & Chr(10))区切りでStringBuilderオブジェクトに書き込みます。

 文字列連結には、文字列の連結演算子である「&」演算子を利用することも可能ですが、繰り返し文字列の連結を行う場合には、あらかじめ一定の文字列バッファを確保しておくStringBuilderクラスを利用した方がより効率的な処理が望めます(詳細は「.NET TIPS:文字列を連結するには?」を参考にしてください)。

 これで、管理者に通知するためのメール本文の出来上がりです。

(2)ASP.NETアプリケーションから電子メールを送信する方法

 ASP.NETアプリケーションから電子メールを送信するには、あらかじめ「ASP.NET Webアプリケーション管理ツール」(以降、管理ツール)からメール送信にかかわる基本情報を設定しておく必要があります*2

 この管理ツールはASP.NET 2.0から提供されるようになったブラウザ・ベースの管理アプリケーションで、これを利用することで、アプリケーション開発者はメール・サーバの設定やアクセス/ユーザー管理などの作業を行うために、アプリケーション構成ファイル(Web.config)を直接編集する必要がありません*3

*2 基本情報はプログラム中にハード・コーディングすることも可能ですが、環境によって変動する可能性がある情報を個々の「.aspx」ファイルに記述することは保守性の観点からも好ましくありません。また、配布サンプルではダミーの情報が指定されていますので、使用に当たっては必ず設定を自分の環境に合わせて修正するようにしてください。

*3 アクセス/ユーザー管理を行う方法については、別稿「.NET TIPS:[ASP.NET]セキュリティ・コントロールでログイン機能を作成するには?」などを参照してください。

 管理ツールは、Visual Studio 2005のメニューから[Webサイト]−[ASP.NET構成]を選択することで起動できます。


図12 管理ツール(Webアプリケーション管理ツール)起動時の画面

 メール送信にかかわる情報を設定するには、[アプリケーション]タブから[SMTP 電子メール設定の構成]をクリックします。

 [SMTP設定の構成]画面が起動しますので、表10の要領で必要な情報を定義しておきます(もちろん、具体的な設定値は個々の環境によって異なりますので、適宜、読み替えてください)。

項目 概要 設定値(例)
サーバ名 SMTPサーバのホスト名 smtp.example.co.jp
サーバ・ポート SMTPサーバのポート番号 25
送信元 メール送信時の送信元アドレス CQW15204@nifty.com
認証 メール送信時に必要な認証の種類 なし
表10 [SMTP設定の構成]画面の入力情報

 メール送信にかかわる基本情報を設定したら、あとはカンタンです。

 メール本体を表すのは、MailMessageクラス(System.Net.Mail名前空間)の役割です。MailMessageクラスにメール送信に必要な諸情報を設定していきます。MailMessageクラスで提供される主なプロパティは表11のとおりです。

プロパティ 概要
Attachments 添付ファイルのコレクション
Bcc BCCアドレス(MailAddressオブジェクトのコレクション)
Body メッセージ本文
BodyEncoding メール本文の文字エンコーディング
CC CCアドレス(MailAddressオブジェクトのコレクション)
From 差出人アドレス
Headers メール・ヘッダ
IsBodyHtml メール本文がHTML形式か
Priority 優先順位(High|Normal|Low)
ReplyTo ReplyToアドレス
Subject 件名
SubjectEncoding メール件名の文字エンコーディング
To TOアドレス(MailAddressオブジェクトのコレクション)
表11 MailMessageクラス(System.Net.Mail名前空間)の主なプロパティ

 個々のMailMessageオブジェクトでFromプロパティ(送信元アドレス)を指定することも可能ですが、ここでは管理ツールですでに定義済みですので、あらためて指定する必要はありません。

 必要な情報をセットし終えたら、これをSmtpClient.Sendメソッドで送信します。

[3]カスタム・エラー・ページを定義する

 最後に、例外発生時に表示するカスタムのエラー・ページを定義します。通常、ASP.NETではアプリケーション内で例外が発生した場合に、デフォルトのエラー・ページを表示します。

 しかし、このエラー・ページ、主に開発者向けの用途を意図したもので、エンドユーザーにとっては無意味であるだけでなく、そもそもセキュリティ上、露出するのが好ましくないアプリケーションの内部情報がびっしり書き込まれていたりします。運用時は、セキュリティ/ユーザビリティ双方の観点から、デフォルトのエラー・ページが表示されないよう、必ずカスタム・エラー・ページを指定しておくことを強くお勧めします。

 カスタム・エラー・ページを定義するには、アプリケーション構成ファイル(Web.config)に以下のようなコードを追記してください。

<customErrors mode="On" defaultRedirect="ErrorPage.htm" />
リスト7 カスタム・エラー・ページを有効にするためのコード(Web.config)

 <customErrors>要素のmode属性はカスタム・エラーの表示モードを、defaultRedirect属性はカスタム・エラー・ページのURLを、それぞれ指定します*4。mode属性に指定可能な値は、表12のとおりです。

*4 カスタム・エラー・ページ「ErrorPage.htm」は単なるHTMLページです。ここではその内容については割愛しますので、詳細は配布サンプルから確認してください。

設定値 概要
On カスタム・エラー・ページは常に有効
Off カスタム・エラー・ページは無効(常に開発者向けのエラー・ページを表示)
RemoteOnly リモート接続のユーザーにのみカスタム・エラー・ページを表示。ローカル接続のユーザーには開発者向けのエラー・ページを表示(デフォルト)
表12 <customErrors>要素のmode属性で指定可能な値

 リスト7ではカスタム・エラー・ページをローカル環境でも確認できるよう、"On"値を指定していますが、通常は、ローカル(開発)環境では通常のエラー情報を表示するよう、"RemoteOnly"値にしておくのが便利でしょう。セキュリティ上はお勧めできませんが、"Off"値に指定することで、リモート環境でもデフォルトのエラー情報画面を表示させることも可能です。

 以上を理解したら、さっそくコードの動作を確認してみましょう。(例えば)SQL Serverのサービスを停止し、先ほど作成したRssFeed.aspxを実行します。本節冒頭の図11のようにカスタムのエラー・ページが表示され、かつ、指定したメール・アドレスにエラー通知メールが送信されていれば成功です。

 以上、今回はここまでです。本サンプルの例を見ても分かるように、ASP.NET 2.0の機能は実に多彩です。定型的な機能はサーバ・コントロールに任せつつ、わずかなコードを加えるのみで、さまざまな機能を柔軟に実装できることが本稿を通じて少しでもイメージしていただけたのならば幸いです。

 さて、次回はいよいよ最終回、これまでに扱えなかったデータベース関連の主要なテクニックについてTIPS形式で紹介していく予定です。お楽しみに。End of Article


 INDEX
  Visual Studio 2005でいってみようDBプログラミング
  第11回 実践アプリケーションでもっと踏み込むASP.NET 2.0の世界
    1.掲示板アプリケーションに画像アップロード機能を追加する(1)
    2.掲示板アプリケーションに画像アップロード機能を追加する(2)
    3.掲示板の更新情報をRSSフィードで配信する
  4.アプリケーション・エラーに関する情報を管理者にメールで通知する
 
インデックス・ページヘ  「Visual Studio 2005でいってみようDBプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間