ASP.NET エラー処理

作成者: Erik Reitan

Wingtip Toys サンプル プロジェクト (C#) をダウンロードするか電子書籍 (PDF) をダウンロードしてください

このチュートリアル シリーズでは、ASP.NET 4.5 と Microsoft Visual Studio Express 2013 for Web を使った ASP.NET Web Forms アプリケーション構築の基本について説明します。 Visual Studio 2013 の C# ソース コードを含むプロジェクトは、このチュートリアル シリーズへの関連付けに使用できます。

このチュートリアルでは、エラー処理とエラー ログを含むように Wingtip Toys サンプル アプリケーションを変更します。 エラー処理を行うと、このアプリケーションで、エラーを適切に処理して、それに応じてエラー メッセージを表示できるようになります。 エラー ログを記録すると、発生したエラーを検出して修正できるようになります。 このチュートリアルは、前のチュートリアル「UTL ルーティング」に基づいており、Wingtip Toys チュートリアル シリーズの一部を成しています。

ここでは、次の内容について学習します。

  • アプリケーションの構成にグローバル エラー処理を追加する方法。
  • アプリケーション、ページ、コード レベルでエラー処理を追加する方法。
  • 後で確認できるようにエラーをログに記録する方法。
  • セキュリティを侵害しないエラー メッセージを表示する方法。
  • Error Logging Modules and Handlers (ELMAH) エラー ログを実装する方法。

概要

ASP.NET アプリケーションには、実行中に発生したエラーを一貫した方法で処理する機能が必要です。 ASP.NET では、均一な方法でアプリケーションにエラーを通知する方法が用意されている共通言語ランタイム (CLR) を使用します。 エラーが発生すると、例外がスローされます。 例外とは、アプリケーションで発生したエラー、条件、または予期しない動作です。

.NET Framework では、例外は System.Exception クラスから継承されるオブジェクトです。 例外は問題が発生したコード領域からスローされます。 この例外は、呼び出し履歴の上位で、例外を処理するためのコードがアプリケーションによって提供されている場所に渡されます。 アプリケーションで例外が処理されない場合は、ブラウザーにエラーの詳細が強制的に表示されます。

ベスト プラクティスとして、コード内の Try/Catch/Finally ブロックのコード レベルでエラーを処理します。 問題が発生したコンテキスト内でユーザーがそれらを修正できるように、これらのブロックを配置してみてください。 エラー処理ブロックがエラーの発生元から離れすぎている場合は、問題の修正に必要な情報をユーザーに提供することが困難になります。

例外クラス

Exception クラスは、例外の継承元となる基底クラスです。 ほとんどの例外オブジェクトは、SystemException クラス、IndexOutOfRangeException クラス、または ArgumentNullException クラスなど、Exception クラスの一部の派生クラスのインスタンスです。 Exception クラスには、StackTrace プロパティ、InnerException プロパティ、Message プロパティなど、発生したエラーに関する特定の情報を提供するプロパティがあります。

例外継承階層

ランタイムには、例外が発生したときにランタイムによってスローされる SystemException クラスから派生する例外の基本セットがあります。 IndexOutOfRangeException クラスや ArgumentNullException クラスなど、Exception クラスを継承するクラスのほとんどでは、追加のメンバーが実装されません。 そのため、例外の最も重要な情報は、例外の階層、例外の名前、例外に含まれる情報で見つけることができます。

例外処理階層

ASP.NET Web Forms アプリケーションでは、特定の処理階層に基づいて例外を処理できます。 例外は、次のレベルで処理できます。

  • アプリケーション レベル
  • ページ レベル
  • コード レベル

アプリケーションで例外が処理されると、多くの場合、Exception クラスから継承された例外に関する追加情報の取得とユーザーへの表示が行われます。 アプリケーション、ページ、コード レベルに加え、HTTP モジュール レベルでの例外の処理や IIS カスタム ハンドラーを使用した例外の処理も可能です。

アプリケーション レベルのエラー処理

アプリケーションレベルで既定のエラーを処理するには、アプリケーションの構成を変更するか、アプリケーションの Global.asax ファイルに Application_Error ハンドラーを追加します。

既定のエラーや HTTP エラーを処理するには、customErrors セクションを Web.config ファイルに追加します。 customErrors セクションでは、エラーが発生した場合にユーザーのリダイレクト先となる既定のページを指定できます。 また、特定の状態コード エラーに対して個々のページを指定することもできます。

<configuration>
  <system.web>
    <customErrors mode="On" defaultRedirect="ErrorPage.aspx?handler=customErrors%20section%20-%20Web.config">
      <error statusCode="404" redirect="ErrorPage.aspx?msg=404&amp;handler=customErrors%20section%20-%20Web.config"/>
    </customErrors>
  </system.web>
</configuration>

残念ながら、ユーザーを別のページにリダイレクトするために構成を使用する場合は、発生したエラーの詳細を確認することができません。

ただし、Global.asax ファイル内の Application_Error ハンドラーにコードを追加すると、アプリケーション内のどこで発生したエラーであってもトラップできます。

void Application_Error(object sender, EventArgs e)
{
    Exception exc = Server.GetLastError();

    if (exc is HttpUnhandledException)
    {
        // Pass the error on to the error page.
        Server.Transfer("ErrorPage.aspx?handler=Application_Error%20-%20Global.asax", true);
    }
}

ページ レベルのエラー イベント処理

ページ レベルのハンドラーは、エラーが発生したページにユーザーを返しますが、コントロールのインスタンスは維持されないため、ページ上には何も表示されなくなります。 アプリケーションのユーザーにエラーの詳細を表示するには、エラーの詳細を具体的にページに書き込む必要があります。

通常は、ページ レベルのエラー ハンドラーを使用して、未処理のエラーをログに記録するか、有用な情報を表示できるページにユーザーを移動します。

このコード例では、ASP.NET Web ページの Error イベントのハンドラーを示しています。 このハンドラーを使用すると、ページ内の try/catch ブロック内にある未処理の例外がすべてキャッチされます。

private void Page_Error(object sender, EventArgs e)
{
    Exception exc = Server.GetLastError();

    // Handle specific exception.
    if (exc is HttpUnhandledException)
    {
        ErrorMsgTextBox.Text = "An error occurred on this page. Please verify your " +                  
        "information to resolve the issue."
    }
    // Clear the error from the server.
    Server.ClearError();
}

エラーは、処理した後、Server オブジェクト (HttpServerUtility クラス) の ClearError メソッドを呼び出して消去する必要があります。そうしないと、以前に発生したエラーが表示されます。

コード レベルのエラー処理

try-catch ステートメントは、try ブロックと、それに続く 1 つ以上の catch 句で構成されます。これらにより、さまざまな例外のハンドラーが指定されます。 例外がスローされると、共通言語ランタイム (CLR) では、この例外を処理する catch ステートメントの検索が行われます。 現在実行されているメソッドにそのような catch ブロックが含まれていない場合、CLR では、呼び出し履歴の上位で、現在のメソッドを呼び出したメソッドの検索が行われます。 catch ブロックが見つからない場合、CLR では、未処理の例外のメッセージがユーザーに表示されてプログラムの実行が停止します。

次のコード例は、try/catch/finally を使用してエラーを処理する一般的な方法を示しています。

try
{
    file.ReadBlock(buffer, index, buffer.Length);
}
catch (FileNotFoundException e)
{
    Server.Transfer("NoFileErrorPage.aspx", true);
}
catch (System.IO.IOException e)
{
    Server.Transfer("IOErrorPage.aspx", true);
}

finally
{
    if (file != null)
    {
        file.Close();
    }
}

上記のコードでは、可能性のある例外から保護する必要があるコードが try ブロックに含まれています。 このブロックは、例外がスローされるか、ブロックが正常に完了するまで実行されます。 FileNotFoundException 例外または IOException 例外が発生した場合、その実行は別のページに転送されます。 その後、エラーが発生したかどうかに関係なく、finally ブロックに含まれているコードが実行されます。

エラー ログのサポートの追加

Wingtip Toys サンプル アプリケーションにエラー処理を追加する前に、ExceptionUtility クラスを Logic フォルダーに追加して、エラー ログのサポートを追加します。 これを行うことで、アプリケーションでエラーが処理されるたびに、エラーの詳細がエラー ログ ファイルに追加されます。

  1. Logic フォルダーを右クリックして [追加] ->[新しい項目] を選択します。
    [新しい項目の追加] ダイアログ ボックスが表示されます。

  2. 左側の [Visual C#] ->Code テンプレート グループを選択します。 次に、中央の一覧から [クラス] を選択して、「ExceptionUtility.cs」という名前を付けます。

  3. 追加を選択します。 新しいクラス ファイルが表示されます。

  4. 既存のコードを次のコードに置き換えます。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.IO;
    
    namespace WingtipToys.Logic
    {
      // Create our own utility for exceptions
      public sealed class ExceptionUtility
      {
        // All methods are static, so this can be private
        private ExceptionUtility()
        { }
    
        // Log an Exception
        public static void LogException(Exception exc, string source)
        {
          // Include logic for logging exceptions
          // Get the absolute path to the log file
          string logFile = "~/App_Data/ErrorLog.txt";
          logFile = HttpContext.Current.Server.MapPath(logFile);
    
          // Open the log file for append and write the log
          StreamWriter sw = new StreamWriter(logFile, true);
          sw.WriteLine("********** {0} **********", DateTime.Now);
          if (exc.InnerException != null)
          {
            sw.Write("Inner Exception Type: ");
            sw.WriteLine(exc.InnerException.GetType().ToString());
            sw.Write("Inner Exception: ");
            sw.WriteLine(exc.InnerException.Message);
            sw.Write("Inner Source: ");
            sw.WriteLine(exc.InnerException.Source);
            if (exc.InnerException.StackTrace != null)
            {
              sw.WriteLine("Inner Stack Trace: ");
              sw.WriteLine(exc.InnerException.StackTrace);
            }
          }
          sw.Write("Exception Type: ");
          sw.WriteLine(exc.GetType().ToString());
          sw.WriteLine("Exception: " + exc.Message);
          sw.WriteLine("Source: " + source);
          sw.WriteLine("Stack Trace: ");
          if (exc.StackTrace != null)
          {
            sw.WriteLine(exc.StackTrace);
            sw.WriteLine();
          }
          sw.Close();
        }
      }
    }
    

例外が発生したら、LogException メソッドを呼び出すと、その例外を例外ログ ファイルに書き込むことができます。 このメソッドは、例外オブジェクトと、例外のソースに関する詳細を含む文字列という 2 つのパラメータを受け取ります。 例外ログは、App_Data フォルダー内の ErrorLog.txt ファイルに書き込まれます。

エラー ページの追加

Wingtip Toys サンプル アプリケーションでは、エラーを表示するために 1 つのページを使用します。 エラー ページは、セキュリティで保護されたエラー メッセージをサイトのユーザーに向けて表示するように設計されています。 ただし、そのユーザーが、コードが存在するマシン上でローカルに提供されている HTTP 要求を行う開発者である場合、エラー ページには、エラーのその他の詳細が表示されます。

  1. ソリューション エクスプローラーでプロジェクト名 (Wingtip Toys) を右クリックして、[追加] ->[新しい項目] を選択します。
    [新しい項目の追加] ダイアログ ボックスが表示されます。

  2. 左側の [Visual C#] ->Web テンプレート グループを選択します。 中央の一覧から、[マスター ページを含む Web フォーム] を選択して、それに「ErrorPage.aspx」という名前を付けます。

  3. 追加をクリックします。

  4. Site.Master ファイルをマスター ページとして選択して、[OK] を選択します。

  5. 既存のマークアップを次に置き換えます。

    <%@ Page Title="" Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.Master"  CodeBehind="ErrorPage.aspx.cs" Inherits="WingtipToys.ErrorPage" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
        <h2>Error:</h2>
        <p></p>
        <asp:Label ID="FriendlyErrorMsg" runat="server" Text="Label" Font-Size="Large" style="color: red"></asp:Label>
    
        <asp:Panel ID="DetailedErrorPanel" runat="server" Visible="false">
            <p>&nbsp;</p>
            <h4>Detailed Error:</h4>
            <p>
                <asp:Label ID="ErrorDetailedMsg" runat="server" Font-Size="Small" /><br />
            </p>
    
            <h4>Error Handler:</h4>
            <p>
                <asp:Label ID="ErrorHandler" runat="server" Font-Size="Small" /><br />
            </p>
    
            <h4>Detailed Error Message:</h4>
            <p>
                <asp:Label ID="InnerMessage" runat="server" Font-Size="Small" /><br />
            </p>
            <p>
                <asp:Label ID="InnerTrace" runat="server"  />
            </p>
        </asp:Panel>
    </asp:Content>
    
  6. 分離コード (ErrorPage.aspx.cs) の既存のコードを次のように置き換えます。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using WingtipToys.Logic;
    
    namespace WingtipToys
    {
      public partial class ErrorPage : System.Web.UI.Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
          // Create safe error messages.
          string generalErrorMsg = "A problem has occurred on this web site. Please try again. " +
              "If this error continues, please contact support.";
          string httpErrorMsg = "An HTTP error occurred. Page Not found. Please try again.";
          string unhandledErrorMsg = "The error was unhandled by application code.";
    
          // Display safe error message.
          FriendlyErrorMsg.Text = generalErrorMsg;
    
          // Determine where error was handled.
          string errorHandler = Request.QueryString["handler"];
          if (errorHandler == null)
          {
            errorHandler = "Error Page";
          }
    
          // Get the last error from the server.
          Exception ex = Server.GetLastError();
    
          // Get the error number passed as a querystring value.
          string errorMsg = Request.QueryString["msg"];
          if (errorMsg == "404")
          {
            ex = new HttpException(404, httpErrorMsg, ex);
            FriendlyErrorMsg.Text = ex.Message;
          }
    
          // If the exception no longer exists, create a generic exception.
          if (ex == null)
          {
            ex = new Exception(unhandledErrorMsg);
          }
    
          // Show error details to only you (developer). LOCAL ACCESS ONLY.
          if (Request.IsLocal)
          {
            // Detailed Error Message.
            ErrorDetailedMsg.Text = ex.Message;
    
            // Show where the error was handled.
            ErrorHandler.Text = errorHandler;
    
            // Show local access details.
            DetailedErrorPanel.Visible = true;
    
            if (ex.InnerException != null)
            {
              InnerMessage.Text = ex.GetType().ToString() + "<br/>" +
                  ex.InnerException.Message;
              InnerTrace.Text = ex.InnerException.StackTrace;
            }
            else
            {
              InnerMessage.Text = ex.GetType().ToString();
              if (ex.StackTrace != null)
              {
                InnerTrace.Text = ex.StackTrace.ToString().TrimStart();
              }
            }
          }
    
          // Log the exception.
          ExceptionUtility.LogException(ex, errorHandler);
    
          // Clear the error from the server.
          Server.ClearError();
        }
      }
    }
    

エラー ページが表示されたら、Page_Load イベント ハンドラーが実行されます。 Page_Load ハンドラーでは、エラーが最初に処理された場所が判断されます。 次に、最後に発生したエラーが、Server オブジェクトの GetLastError メソッドを呼び出すことで判断されます。 例外がそれ以上存在していない場合は、汎用例外が作成されます。 その後、HTTP 要求がローカルで行われた場合は、エラーのすべての詳細が表示されます。 この場合、Web アプリケーションが実行されているローカル コンピューターにのみ、これらのエラーの詳細が表示されます。 エラー情報が表示されると、エラーがログ ファイルに追加され、サーバーからエラーが消去されます。

アプリケーションの未処理のエラー メッセージの表示

customErrors セクションを Web.config ファイルに追加すると、アプリケーション全体で発生している単純なエラーならすぐに処理できます。 また、"404 - ファイルが見つかりません" など、状態コード値に戻づいてエラーを処理する方法も指定できます。

構成を更新する

customErrors セクションを Web.config ファイルに追加して、構成を更新します。

  1. ソリューション エクスプローラーで、Wingtip Toys サンプル アプリケーションのルート上にある Web.config ファイルを見つけて開きます。

  2. 次のように、<system.web> ノード内で、customErrors セクションを Web.config ファイルに追加します。

    <configuration>
      <system.web>
        <customErrors mode="On" defaultRedirect="ErrorPage.aspx?handler=customErrors%20section%20-%20Web.config">
          <error statusCode="404" redirect="ErrorPage.aspx?msg=404&amp;handler=customErrors%20section%20-%20Web.config"/>
        </customErrors>
      </system.web>
    </configuration>
    
  3. Web.config ファイルを保存します。

customErrors セクションでは、[オン] に設定されているモードが指定されます。 また、エラーが発生した場合の移動先のページをアプリケーションに指示する defaultRedirect も指定されます。 さらに、ページが見つからない場合に 404 エラーを処理する方法を指定する特定のエラー要素が追加されています。 このチュートリアルでは、この後、アプリケーション レベルでエラーの詳細をキャプチャするその他のエラー処理を追加します。

アプリケーションの実行

ここで、アプリケーションを実行して、更新されたルートを確認できます。

  1. F5 キーを押して、Wingtip Toys サンプル アプリケーションを実行します。
    ブラウザーが開き、Default.aspx ページが表示されます。

  2. 次の URL をブラウザーに入力します (必ずご自身のポート番号を使用してください)。
    https://localhost:44300/NoPage.aspx

  3. ブラウザーに表示されている ErrorPage.aspx を確認します。

    ASP.NET Error Handling - Page Not Found Error

存在しない NoPage.aspx ページを要求すると、エラー ページには、単純なエラー メッセージが表示されます。その他の詳細がある場合は、詳細なエラー情報が表示されます。 ただし、存在しないページをユーザーがリモートの場所から要求した場合、エラー ページには、エラー メッセージのみが赤色で表示されます。

テスト目的の例外を含める

エラーが発生した場合のアプリケーションの動作を確認するには、ASP.NET でエラー条件を注意深く作成するのがよいでしょう。 Wingtip Toys サンプル アプリケーションでは、既定のページが読み込まれたら、テスト例外をスローして様子を見ます。

  1. Visual Studio で、Default.aspx ページの分離コードを開きます。
    Default.aspx.cs 分離コード ページが表示されます。

  2. Page_Load ハンドラーでコードを追加して、このハンドラーを次のようにします。

    protected void Page_Load(object sender, EventArgs e)
    {
        throw new InvalidOperationException("An InvalidOperationException " +
        "occurred in the Page_Load handler on the Default.aspx page.");
    }
    

さまざまな種類の例外を作成することが可能です。 上記のコードでは、Default.aspx ページが読み込まれるときに InvalidOperationException を作成しています。

アプリケーションの実行

アプリケーションを実行して、アプリケーションでどのように例外が処理されるかを確認できます。

  1. Ctrl + F5 キーを押して、Wingtip Toys サンプル アプリケーションを実行します。
    アプリケーションが InvalidOperationException をスローします。

    Note

    Visual Studio でエラーのソースを表示するコードに分割せずにページを表示するには、Ctrl + F5 キーを押す必要があります。

  2. ブラウザーに表示されている ErrorPage.aspx を確認します。

    ASP.NET Error Handling - Error Page

エラーの詳細からわかるように、Web.config ファイルの customError セクションによって例外がトラップされています。

アプリケーション レベルのエラー処理の追加

Web.config ファイルの customErrors セクションでは例外に関する情報をほとんど得ることができないため、これを使う代わりに、アプリケーション レベルでエラーをトラップしてエラーの詳細を取得します。

  1. ソリューション エクスプローラーで、Global.asax.cs ファイルを見つけて開きます。

  2. Application_Error ハンドラーを次のように追加します。

    void Application_Error(object sender, EventArgs e)
    {
      // Code that runs when an unhandled error occurs.
    
      // Get last error from the server
      Exception exc = Server.GetLastError();
    
      if (exc is HttpUnhandledException)
      {
        if (exc.InnerException != null)
        {
          exc = new Exception(exc.InnerException.Message);
          Server.Transfer("ErrorPage.aspx?handler=Application_Error%20-%20Global.asax",
              true);
        }
      }
    }
    

アプリケーションでエラーが発生すると、Application_Error ハンドラーが呼び出されます。 このハンドラーでは、最後の例外の取得と確認が行われます。 例外が未処理で、例外に内部例外の詳細 (つまり、InnerException は null ではありません) が含まれている場合、アプリケーションでは、例外の詳細が表示されているエラー ページに実行が転送されます。

アプリケーションの実行

アプリケーション レベルで例外を処理すると提供されるエラーのその他の詳細を確認するには、アプリケーションを実行します。

  1. Ctrl + F5 キーを押して、Wingtip Toys サンプル アプリケーションを実行します。
    アプリケーションが InvalidOperationException をスローします。

  2. ブラウザーに表示されている ErrorPage.aspx を確認します。

    ASP.NET Error Handling - Application Level Error

ページ レベルのエラー処理の追加

ページ レベルのエラー処理をページに追加するには、ページの @Page ディレクティブに ErrorPage 属性を追加するか、ページの分離コードに Page_Error イベント ハンドラーを追加します。 このセクションでは、実行を転送する Page_Error イベント ハンドラーを ErrorPage.aspx ページに追加します。

  1. ソリューション エクスプローラーで、Default.aspx.cs ファイルを見つけて開きます。

  2. Page_Error ハンドラーを追加して、分離コードを次のようにします。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace WingtipToys
    {
      public partial class _Default : Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
          throw new InvalidOperationException("An InvalidOperationException " +
          "occurred in the Page_Load handler on the Default.aspx page.");
        }
    
        private void Page_Error(object sender, EventArgs e)
        {
          // Get last error from the server.
          Exception exc = Server.GetLastError();
    
          // Handle specific exception.
          if (exc is InvalidOperationException)
          {
            // Pass the error on to the error page.
            Server.Transfer("ErrorPage.aspx?handler=Page_Error%20-%20Default.aspx",
                true);
          }
        }
      }
    }
    

ページでエラーが発生すると、Page_Error イベント ハンドラーが呼び出されます。 このハンドラーでは、最後の例外の取得と確認が行われます。 InvalidOperationException が発生した場合は、Page_Error イベント ハンドラーによって、例外の詳細が表示されているエラー ページに実行が転送されます。

アプリケーションの実行

ここで、アプリケーションを実行して、更新されたルートを確認できます。

  1. Ctrl + F5 キーを押して、Wingtip Toys サンプル アプリケーションを実行します。
    アプリケーションが InvalidOperationException をスローします。

  2. ブラウザーに表示されている ErrorPage.aspx を確認します。

    ASP.NET Error Handling - Page Level Error

  3. ブラウザー ウィンドウを閉じます。

テストに使用される例外の削除

このチュートリアルで前に追加した例外をスローせずに Wingtip Toys サンプル アプリケーションを機能させるには、例外を削除します。

  1. Default.aspx ページの分離コードを開きます。

  2. Page_Load ハンドラーで、例外をスローするコードを削除して、ハンドラーを次のようにします。

    protected void Page_Load(object sender, EventArgs e)
    {
    
    }
    

コード レベルのエラー ログの追加

このチュートリアルで前述したように、try ステートメントと catch ステートメントを追加して、コードのセクションを実行し、発生した最初のエラーを処理することができます。 この例では、エラーの詳細のみをエラー ログ ファイルに書き込んで、後でエラーを確認できるようにします。

  1. ソリューション エクスプローラーで、Logic フォルダー内にある PayPalFunctions.cs ファイルを見つけて開きます。

  2. HttpCall メソッドを更新して、コードを次のようにします。

    public string HttpCall(string NvpRequest)
    {
      string url = pEndPointURL;
    
      string strPost = NvpRequest + "&" + buildCredentialsNVPString();
      strPost = strPost + "&BUTTONSOURCE=" + HttpUtility.UrlEncode(BNCode);
    
      HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
      objRequest.Timeout = Timeout;
      objRequest.Method = "POST";
      objRequest.ContentLength = strPost.Length;
    
      try
      {
        using (StreamWriter myWriter = new StreamWriter(objRequest.GetRequestStream()))
        {
          myWriter.Write(strPost);
        }
      }
      catch (Exception e)
      {
        // Log the exception.
        WingtipToys.Logic.ExceptionUtility.LogException(e, "HttpCall in PayPalFunction.cs");
      }
    
      //Retrieve the Response returned from the NVP API call to PayPal.
      HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
      string result;
      using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
      {
        result = sr.ReadToEnd();
      }
    
      return result;
    }
    

上記のコードを使うと、ExceptionUtility クラスに含まれる LogException メソッドを呼び出すことができます。 このチュートリアルでは先ほど、ExceptionUtility.cs クラス ファイルを Logic フォルダーに追加しました。 LogException は、次の 2 つのパラメーターを受け取ります。 最初のパラメータは例外オブジェクトです。 2 番目のパラメータは、エラーのソースを認識するために使用される文字列です。

エラー ログ情報の検査

前述したように、エラー ログを使用して、アプリケーション内のエラーのうち最初に修正する必要があるものを判断できます。 もちろん、トラップされてエラー ログに書き込まれたエラーのみが記録されます。

  1. ソリューション エクスプローラーで、App_Data フォルダー内の ErrorLog.txt ファイルを見つけて開きます。
    ErrorLog.txt ファイルを表示するには、ソリューション エクスプローラーの上部で [すべてのファイルを表示] オプションまたは [最新の情報に更新] オプションを見つけます。

  2. Visual Studio に表示されるエラー ログを確認します。

    ASP.NET Error Handling - ErrorLog.txt

安全なエラー メッセージ

アプリケーションにエラー メッセージが表示されるときに、悪意のあるユーザーがそのアプリケーションを攻撃するのに役立つ情報をそこに含めないように注意することが重要です。 たとえば、アプリケーションでデータベースへの書き込みが失敗した場合に表示されるエラー メッセージには、使用されているユーザー名が含まれないようにする必要があります。 このため、ユーザーには、一般的なエラー メッセージが赤色で表示されます。 エラーのその他の詳細はすべて、ローカル コンピューター上の開発者にのみ表示されます。

ELMAH の使用

ELMAH (Error Logging Modules and Handlers) は、NuGet パッケージとして ASP.NET アプリケーションに接続するエラー ログ機能です。 ELMAH には、次の機能があります。

  • 未処理の例外のログ記録。
  • 再コーディングされた未処理の例外のログ全体を表示する Web ページ。
  • ログに記録された各例外のすべての詳細を表示する Web ページ。
  • 各エラーが発生した時点のメール通知。
  • ログからの過去 15 件のエラーの RSS フィード。

ELMAH を使うには、インストールする必要があります。 これには、NuGet パッケージ インストーラーを使うと簡単です。 このチュートリアル シリーズで前述したように、NuGet は Visual Studio 拡張機能であり、これを使うと、Visual Studio でのオープン ソース ライブラリやツールのインストールや更新が簡単になります。

  1. Visual Studio 内の [ツール] メニューで、[NuGet パッケージ マネージャー]>[ソリューションの NuGet パッケージの管理] を選択します。

    ASP.NET Error Handling - Manage NuGet Packages for Solution

  2. Visual Studio 内に [NuGet パッケージの管理] ダイアログ ボックスが表示されます。

  3. [NuGet パッケージの管理] ダイアログ ボックスで、左側の [オンライン] を展開して nuget.org を選択します。次に、オンラインで使用可能なパッケージの一覧から ELMAH パッケージを見つけてインストールします。

    ASP.NET Error Handling - ELMA NuGet Package

  4. パッケージをダウンロードするには、インターネットに接続する必要があります。

  5. [プロジェクトの選択] ダイアログ ボックスで、WingtipToys の選択内容が選択されていることを確認して、[OK] をクリックします。

    ASP.NET Error Handling - Select Projects Dialog

  6. 必要に応じて、[NuGet パッケージの管理] ダイアログ ボックスの [閉じる] をクリックします。

  7. 開いているファイルを再読み込みするように要求するメッセージが Visual Studio に表示された場合は、[すべてはい] を選択します。

  8. ELMAH パッケージによって、それ自体のエントリが、プロジェクトのルートにある Web.config ファイルに追加されます。 変更した Web.config ファイルを再読み込みするかどうかを確認するメッセージが Visual Studio に表示された場合は、[はい] をクリックします。

これで ELMAH は、発生した未処理のエラーを格納する準備ができました。

ELMAH ログの表示

ELMAH ログは簡単に表示できますが、まずは、ELMAH ログに記録される未処理の例外を作成します。

  1. Ctrl + F5 キーを押して、Wingtip Toys サンプル アプリケーションを実行します。

  2. 未処理の例外を ELMAH ログに書き込むには、ブラウザーで次の URL に移動します (ご自身のポート番号を使います):
    https://localhost:44300/NoPage.aspx エラー ページが表示されます。

  3. ELMAH ログを表示するには、ブラウザーで次の URL に移動します (ご自身のポート番号を使います):
    https://localhost:44300/elmah.axd

    ASP.NET Error Handling - ELMAH Error Log

まとめ

このチュートリアルでは、アプリケーション レベル、ページ レベル、コード レベルでエラーを処理する方法について説明しました。 また、処理されたエラーと未処理のエラーを後で確認できるようにログに記録する方法についても説明しました。 NuGet を使ってアプリケーションに例外ログと通知を提供する ELMAH ユーティリティを追加しました。 さらに、安全なエラー メッセージの重要性についても説明しました。

チュートリアル シリーズのまとめ

お読みいただきありがとうございました。 この一連のチュートリアルをお読みいただいたことで、ASP.NET Web Forms への理解が深まっていれば幸いです。 ASP.NET 4.5 と Visual Studio 2013 で使用可能な Web Forms 機能に関する詳細については、「Visual Studio 2013 の ASP.NET と Web ツールのリリース ノート」を参照してください。 また、「次のステップ」セクションで取り上げているチュートリアルに目を通すようにしてください。また、無料の Azure 試用版をぜひお試しください。

Thanks - Erik

次のステップ

Web アプリケーションを Microsoft Azure にデプロイする方法の詳細については、メンバーシップ、OAuth、SQL Database を使って安全な ASP.NET Web Forms アプリを Azure Web サイトにデプロイする方法に関する記事を参照してください。

無料試用版

Microsoft Azure - 無料試用版
Web サイトを Microsoft Azure に公開すると、時間と費用を節約し、保守の手間を省くことができます。 これは、Web アプリを Azure にデプロイするための簡単なプロセスです。 Web アプリを保守および監視する必要があるなら、Azure にはさまざまなツールとサービスが用意されています。 Azure で、データ、トラフィック、ID、バックアップ、メッセージ、メディア、パフォーマンスを管理します。 そして、このすべてが、非常にコスト効率に優れたアプローチで提供されます。

その他のリソース

エラーの詳細を ASP.NET 正常性監視を使ってログに記録する
ELMAH

確認

このチュートリアル シリーズのコンテンツに多大な貢献を果たした次の方々に感謝を捧げます。

コミュニティへの投稿