다음을 통해 공유


ASP.NET 오류 처리

작성자: Erik Reitan

Wingtip Toys 샘플 프로젝트 다운로드(C#) 또는 전자책 다운로드(PDF)

이 자습서 시리즈에서는 웹용 ASP.NET 4.5 및 Microsoft Visual Studio Express 2013을 사용하여 ASP.NET Web Forms 애플리케이션을 빌드하는 기본 사항을 설명합니다. C# 소스 코드가 있는 Visual Studio 2013 프로젝트는 이 자습서 시리즈와 함께 사용할 수 있습니다.

이 자습서에서는 오류 처리 및 오류 로깅을 포함하도록 Wingtip Toys 샘플 애플리케이션을 수정합니다. 오류 처리를 통해 애플리케이션은 오류를 정상적으로 처리하고 그에 따라 오류 메시지를 표시할 수 있습니다. 오류 로깅을 사용하면 발생한 오류를 찾아 수정할 수 있습니다. 이 자습서는 이전 자습서 "URL 라우팅"을 기반으로 하며 Wingtip Toys 자습서 시리즈의 일부입니다.

학습할 내용:

  • 애플리케이션의 구성에 전역 오류 처리를 추가하는 방법입니다.
  • 애플리케이션, 페이지 및 코드 수준에서 오류 처리를 추가하는 방법입니다.
  • 나중에 검토할 수 있도록 오류를 기록하는 방법입니다.
  • 보안을 손상시키지 않는 오류 메시지를 표시하는 방법입니다.
  • ELMAH(오류 로깅 모듈 및 처리기) 오류 로깅을 구현하는 방법입니다.

개요

ASP.NET 애플리케이션은 일관된 방식으로 실행 중에 발생하는 오류를 처리할 수 있어야 합니다. ASP.NET CLR(공용 언어 런타임)을 사용하여 애플리케이션에 일관된 방식으로 오류를 알리는 방법을 제공합니다. 오류가 발생하면 예외가 throw됩니다. 예외는 애플리케이션에서 발생하는 오류, 조건 또는 예기치 않은 동작입니다.

.NET Framework에서 예외는 System.Exception에서 상속받은 개체입니다. 예외는 문제가 발생한 코드 영역에서 throw됩니다. 예외는 애플리케이션이 예외를 처리하는 코드를 제공하는 위치에 호출 스택을 전달합니다. 애플리케이션에서 예외를 처리하지 않으면 브라우저에서 오류 세부 정보를 표시해야 합니다.

코드 수준 Try//CatchFinally 내의 블록에서 오류를 처리하는 것이 가장 좋습니다. 사용자가 발생하는 컨텍스트에서 문제를 해결할 수 있도록 이러한 블록을 배치해 보세요. 오류 처리 블록이 오류가 발생한 위치와 너무 멀리 떨어져 있으면 사용자에게 문제를 해결하는 데 필요한 정보를 제공하기가 더 어려워집니다.

예외 클래스

Exception 클래스는 예외가 상속되는 기본 클래스입니다. 대부분의 예외 개체는 클래스, 클래스 또는 ArgumentNullException 클래스와 같은 SystemException Exception 클래스의 일부 파생 클래스의 IndexOutOfRangeException 인스턴스입니다. Exception 클래스에는 발생한 오류에 StackTrace 대한 특정 정보를 제공하는 속성, InnerException 속성 및 속성과 Message 같은 속성이 있습니다.

예외 상속 계층 구조

런타임에는 예외가 발생할 때 런타임이 throw하는 클래스에서 SystemException 파생된 기본 예외 집합이 있습니다. 클래스 및 클래스와 같은 IndexOutOfRangeException Exception 클래스에서 상속되는 대부분의 클래스는 추가 멤버를 ArgumentNullException 구현하지 않습니다. 따라서 예외에 대한 가장 중요한 정보는 예외 계층 구조, 예외 이름 및 예외에 포함된 정보에서 찾을 수 있습니다.

예외 처리 계층

ASP.NET Web Forms 애플리케이션에서는 특정 처리 계층 구조에 따라 예외를 처리할 수 있습니다. 예외는 다음 수준에서 처리할 수 있습니다.

  • 애플리케이션 수준
  • 페이지 수준
  • 코드 수준

애플리케이션이 예외를 처리하는 경우 Exception 클래스에서 상속된 예외에 대한 추가 정보를 검색하여 사용자에게 표시할 수 있습니다. 애플리케이션, 페이지 및 코드 수준 외에도 HTTP 모듈 수준에서 IIS 사용자 지정 처리기를 사용하여 예외를 처리할 수도 있습니다.

애플리케이션 수준 오류 처리

애플리케이션의 구성을 수정하거나 애플리케이션의 Global.asax 파일에 처리기를 추가하여 Application_Error 애플리케이션 수준에서 기본 오류를 처리할 수 있습니다.

Web.config 파일에 섹션을 customErrors 추가하여 기본 오류 및 HTTP 오류를 처리할 수 있습니다. 섹션에서는 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 웹 페이지의 Error 이벤트에 대한 처리기를 보여줍니다. 이 처리기는 페이지의 블록 내에서 try/catch 아직 처리되지 않은 모든 예외를 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 블록 뒤에 다른 예외에 대한 처리기를 지정하는 하나 이상의 catch 절로 구성됩니다. 예외가 throw되면 CLR(공용 언어 런타임)은 이 예외를 처리하는 catch 문을 찾습니다. 현재 실행 중인 메서드에 catch 블록이 없는 경우 CLR은 현재 메서드를 호출한 메서드를 조회하고 호출 스택을 위로 찾습니다. catch 블록을 찾을 수 없는 경우 CLR은 처리되지 않은 예외 메시지를 사용자에게 표시하고 프로그램 실행을 중지합니다.

다음 코드 예제에서는 를 사용하여 try//catchfinally 오류를 처리하는 일반적인 방법을 보여줍니다.

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 블록에는 가능한 예외를 방지해야 하는 코드가 포함되어 있습니다. 예외가 throw되거나 블록이 성공적으로 완료될 때까지 블록이 실행됩니다. FileNotFoundException 예외 또는 예외가 IOException 발생하면 실행이 다른 페이지로 전송됩니다. 그런 다음, 오류가 발생했는지 여부에 관계없이 최종 블록에 포함된 코드가 실행됩니다.

오류 로깅 지원 추가

Wingtip Toys 샘플 애플리케이션에 오류 처리를 추가하기 전에 Logic 폴더에 클래스를 ExceptionUtility 추가하여 오류 로깅 지원을 추가합니다. 이렇게 하면 애플리케이션에서 오류를 처리할 때마다 오류 세부 정보가 오류 로그 파일에 추가됩니다.

  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 하여 예외 로그 파일에 예외를 쓸 수 있습니다. 이 메서드는 예외 개체와 예외 원본에 대한 세부 정보가 포함된 문자열이라는 두 개의 매개 변수를 사용합니다. 예외 로그는 App_Data 폴더의 ErrorLog.txt 파일에 기록됩니다.

오류 페이지 추가

Wingtip Toys 샘플 애플리케이션에서 오류를 표시하는 데 한 페이지가 사용됩니다. 오류 페이지는 사이트의 사용자에게 보안 오류 메시지를 표시하도록 설계되었습니다. 그러나 사용자가 코드가 있는 컴퓨터에서 로컬로 제공되는 HTTP 요청을 만드는 개발자인 경우 오류 페이지에 추가 오류 세부 정보가 표시됩니다.

  1. 솔루션 탐색기 프로젝트 이름(Wingtip Toys)을 마우스 오른쪽 단추로 클릭하고 추가 ->새 항목을 선택합니다.
    새 항목 추가 대화 상자가 표시됩니다.

  2. 왼쪽에서 Visual C# ->Web 템플릿 그룹을 선택합니다. 가운데 목록에서 마스터 페이지가 있는 웹 양식을 선택하고 이름을 ErrorPage.aspx로 지정합니다.

  3. 추가를 클릭합니다.

  4. Site.Master 파일을 master 페이지로 선택한 다음 확인을 선택합니다.

  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.config 파일에 섹션을 추가하여 customErrors 애플리케이션 전체에서 발생하는 간단한 오류를 신속하게 처리할 수 있습니다. 404 - 파일을 찾을 수 없음과 같은 상태 코드 값에 따라 오류를 처리하는 방법을 지정할 수도 있습니다.

구성 업데이트

Web.config 파일에 섹션을 customErrors 추가하여 구성을 업데이트합니다.

  1. 솔루션 탐색기 Wingtip Toys 샘플 애플리케이션의 루트에서 Web.config 파일을 찾아 엽니다.

  2. customErrors 다음과 같이 노드 내의 Web.config 파일에 섹션을 <system.web> 추가합니다.

    <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 모드를 지정합니다. 모드는 "On"으로 설정됩니다. 또한 오류가 발생할 때 탐색할 페이지를 애플리케이션에 알려주는 를 지정 defaultRedirect합니다. 또한 페이지를 찾을 수 없을 때 404 오류를 처리하는 방법을 지정하는 특정 오류 요소를 추가했습니다. 이 자습서의 뒷부분에서는 애플리케이션 수준에서 오류의 세부 정보를 캡처하는 추가 오류 처리를 추가합니다.

애플리케이션 실행

이제 애플리케이션을 실행하여 업데이트된 경로를 볼 수 있습니다.

  1. F5 키를 눌러 Wingtip Toys 샘플 애플리케이션을 실행합니다.
    브라우저가 열리고 Default.aspx 페이지가 표시됩니다.

  2. 브라우저에 다음 URL을 입력합니다(포트 번호를 사용해야 합니다 .).
    https://localhost:44300/NoPage.aspx

  3. 브라우저에 표시된 ErrorPage.aspx 를 검토합니다.

    ASP.NET 오류 처리 - 페이지를 찾을 수 없음 오류

존재하지 않는 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을 throw합니다.

    참고

    Visual Studio에서 오류의 원본을 보려면 코드를 중단하지 않고 Ctrl+F5 키를 눌러 페이지를 표시해야 합니다.

  2. 브라우저에 표시된 ErrorPage.aspx 를 검토합니다.

    ASP.NET 오류 처리 - 오류 페이지

오류 세부 정보에서 볼 수 있듯이 예외는 Web.config 파일의 customError 섹션에 의해 트래핑되었습니다.

Application-Level 오류 처리 추가

예외에 대한 정보가 거의 없는 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 throw합니다.

  2. 브라우저에 표시된 ErrorPage.aspx 를 검토합니다.

    ASP.NET 오류 처리 - 애플리케이션 수준 오류

Page-Level 오류 처리 추가

페이지의 지시문에 특성을 @Page 추가 ErrorPage 하거나 페이지의 코드 숨김에 이벤트 처리기를 추가하여 페이지에 페이지 수준 오류 처리를 추가할 Page_Error 수 있습니다. 이 섹션에서는 ErrorPage.aspx 페이지로 실행을 전송하는 이벤트 처리기를 추가 Page_Error 합니다.

  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 throw합니다.

  2. 브라우저에 표시된 ErrorPage.aspx 를 검토합니다.

    ASP.NET 오류 처리 - 페이지 수준 오류

  3. 브라우저 창을 닫습니다.

테스트에 사용되는 예외 제거

이 자습서의 앞부분에서 추가한 예외를 throw하지 않고 Wingtip Toys 샘플 애플리케이션이 작동하도록 하려면 예외를 제거합니다.

  1. Default.aspx 페이지의 코드 숨김을 엽니다.

  2. 처리기 Page_Load 에서 처리기가 다음과 같이 표시되도록 예외를 throw하는 코드를 제거합니다.

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

Code-Level 오류 로깅 추가

이 자습서의 앞부분에서 설명한 것처럼 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;
    }
    

위의 코드는 클래스에 LogException 포함된 메서드를 호출합니다 ExceptionUtility . 이 자습서의 앞부분에서 Logic 폴더에 ExceptionUtility.cs 클래스 파일을 추가했습니다. LogException 메서드는 두 개의 매개 변수를 사용합니다. 첫 번째 매개 변수는 예외 개체입니다. 두 번째 매개 변수는 오류의 원인을 인식하는 데 사용되는 문자열입니다.

오류 로깅 정보 검사

앞에서 설명한 대로 오류 로그를 사용하여 먼저 수정해야 하는 애플리케이션의 오류를 확인할 수 있습니다. 물론 오류 로그에 갇혀 기록된 오류만 기록됩니다.

  1. 솔루션 탐색기 App_Data 폴더에서ErrorLog.txt 파일을 찾아 엽니다.
    ErrorLog.txt 파일을 보려면 솔루션 탐색기 맨 위에서 "모든 파일 표시" 옵션 또는 "새로 고침" 옵션을 선택해야 할 수 있습니다.

  2. Visual Studio에 표시되는 오류 로그를 검토합니다.

    ASP.NET 오류 처리 - ErrorLog.txt

안전한 오류 메시지

애플리케이션 에서 오류 메시지를 표시할 때 악의적인 사용자가 애플리케이션을 공격하는 데 도움이 될 수 있는 정보를 제공하지 않아야 합니다. 예를 들어 애플리케이션이 데이터베이스에 쓰려고 시도하는 경우 사용 중인 사용자 이름을 포함하는 오류 메시지가 표시되지 않아야 합니다. 이러한 이유로 빨간색의 일반 오류 메시지가 사용자에게 표시됩니다. 모든 추가 오류 세부 정보는 로컬 컴퓨터의 개발자에게만 표시됩니다.

ELMAH 사용

ELMAH(오류 로깅 모듈 및 처리기)는 nuGet 패키지로 ASP.NET 애플리케이션에 연결하는 오류 로깅 기능입니다. ELMAH는 다음과 같은 기능을 제공합니다.

  • 처리되지 않은 예외의 로깅입니다.
  • 다시 코딩된 처리되지 않은 예외의 전체 로그를 볼 수 있는 웹 페이지입니다.
  • 기록된 각 예외의 전체 세부 정보를 볼 수 있는 웹 페이지입니다.
  • 발생한 각 오류에 대한 이메일 알림입니다.
  • 로그의 마지막 15개 오류에 대한 RSS 피드입니다.

ELMAH로 작업하려면 먼저 설치해야 합니다. NuGet 패키지 설치 관리자를 사용하면 쉽습니다. 이 자습서 시리즈의 앞부분에서 설명한 것처럼 NuGet은 Visual Studio에서 오픈 소스 라이브러리 및 도구를 쉽게 설치하고 업데이트할 수 있는 Visual Studio 확장입니다.

  1. Visual Studio 내의 도구 메뉴에서 NuGet 패키지 관리자>솔루션용 NuGet 패키지 관리를 선택합니다.

    ASP.NET 오류 처리 - 솔루션용 NuGet 패키지 관리

  2. Visual Studio 내에 NuGet 패키지 관리 대화 상자가 표시됩니다.

  3. NuGet 패키지 관리 대화 상자의 왼쪽에서 온라인을 확장한 다음, nuget.org 선택합니다. 그런 다음 온라인으로 사용 가능한 패키지 목록에서 ELMAH 패키지를 찾아 설치합니다.

    ASP.NET 오류 처리 - ELMA NuGet 패키지

  4. 패키지를 다운로드하려면 인터넷에 연결되어 있어야 합니다.

  5. 프로젝트 선택 대화 상자에서 WingtipToys 선택 항목이 선택되어 있는지 확인한 다음 확인을 클릭합니다.

    ASP.NET 오류 처리 - 프로젝트 선택 대화 상자

  6. 필요한 경우 NuGet 패키지 관리 대화 상자에서 기를 클릭합니다.

  7. Visual Studio에서 열려 있는 파일을 다시 로드하도록 요청하는 경우 "모두 예"를 선택합니다.

  8. ELMAH 패키지는 프로젝트의 루트에 있는 Web.config 파일에 자체 항목을 추가합니다. Visual Studio에서 수정된 Web.config 파일을 다시 로드할지 묻는 메시지가 표시되면 예를 클릭합니다.

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 오류 처리 - ELMAH 오류 로그

요약

이 자습서에서는 애플리케이션 수준, 페이지 수준 및 코드 수준에서 오류를 처리하는 방법을 알아보았습니다. 또한 나중에 검토할 수 있도록 처리된 오류와 처리되지 않은 오류를 기록하는 방법도 알아보았습니다. NuGet을 사용하여 애플리케이션에 예외 로깅 및 알림을 제공하기 위해 ELMAH 유틸리티를 추가했습니다. 또한 안전한 오류 메시지의 중요성에 대해 알아보았습니다.

자습서 시리즈 결론

함께 따라 주셔서 감사합니다. 이 자습서 집합이 ASP.NET Web Forms 익숙해지는 데 도움이 되기를 바랍니다. ASP.NET 4.5 및 Visual Studio 2013 사용할 수 있는 Web Forms 기능에 대한 자세한 내용은 Visual Studio 2013 릴리스 정보 ASP.NET 및 Web Tools 참조하세요. 또한 다음 단계 섹션에 언급된 자습서를 살펴보고 무료 Azure 평가판을 정의하여 사용해 보세요.

감사합니다 - Erik

다음 단계

Microsoft Azure에 웹 애플리케이션을 배포하는 방법에 대한 자세한 내용은 Membership, OAuth 및 SQL Database 사용하여 Azure 웹 사이트에 보안 ASP.NET Web Forms 앱 배포를 참조하세요.

평가판

Microsoft Azure - 평가판
Microsoft Azure에 웹 사이트를 게시하면 시간, 유지 관리 및 비용이 절약됩니다. Azure에 웹앱을 배포하는 빠른 프로세스입니다. 웹앱을 유지 관리하고 모니터링해야 하는 경우 Azure는 다양한 도구와 서비스를 제공합니다. Azure에서 데이터, 트래픽, ID, 백업, 메시징, 미디어 및 성능을 관리합니다. 그리고 이 모든 것은 매우 비용 효율적인 접근 방식으로 제공됩니다.

추가 리소스

ASP.NET 상태 모니터링을 사용하여 오류 세부 정보 로깅
Elmah

감사의 말

이 자습서 시리즈의 콘텐츠에 중요한 기여 다음 사용자에게 감사드립니다.

커뮤니티 기여