首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 錯誤處理機制完整解析:四層防護與優先順序實戰

     編輯:關於ASP.NET

為什麼需要多層錯誤處理?

未處理的例外會顯示「黃色死機畫面」(YSOD)或 IIS 預設錯誤頁,嚇跑使用者、洩露堆疊資訊、破壞信任。ASP.NET 提供四層錯誤處理機制,依範圍從廣到窄:

  1. 應用程式層:web.config <customErrors>、Global.asax Application_Error
  2. 頁面層:Page.ErrorPage 屬性、Page_Error 事件
  3. 控制項/程式碼層:try/catch/finally、using 區塊
  4. HTTP 模組/中介軟體層:自訂 IHttpModule、ASP.NET Core 中介軟體(現代架構)

四大機制詳細比較

1. web.config <customErrors>(舊版) / <httpErrors>(IIS 7+)

<system.web>
  <customErrors mode="On" defaultRedirect="~/Error/GenericError.aspx">
    <error statusCode="404" redirect="~/Error/404.aspx" />
    <error statusCode="500" redirect="~/Error/500.aspx" />
  </customErrors>
</system.web>

<!-- IIS 7+ 整合管線建議使用 httpErrors -->
<system.webServer>
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" />
    <remove statusCode="500" />
    <error statusCode="404" path="/Error/404" responseMode="ExecuteURL" />
    <error statusCode="500" path="/Error/500" responseMode="ExecuteURL" />
  </httpErrors>
</system.webServer>
  • 優點:無需程式碼、支援依狀態碼導向不同頁面、IIS 直接處理靜態檔案錯誤。
  • 缺點:無法記錄例外細節、無法依例外型別處理、重導向會丟失原始 URL 與例外物件。

2. Global.asax Application_Error

protected void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError().GetBaseException();
    // 記錄完整例外(含堆疊、內部例外、請求資訊)
    LogException(ex, Request.Url, Request.UserHostAddress);

    // 清除錯誤,避免觸發 customErrors 重導向
    Server.ClearError();

    // 可選:轉向自訂錯誤頁並傳遞例外 ID
    Response.Redirect("~/Error/GenericError.aspx?exId=" + Guid.NewGuid());
}
  • 關鍵:Server.ClearError() 必須呼叫,否則 ASP.NET 仍會依 customErrors 重導向,導致雙重處理。
  • 適用:集中式日誌記錄、例外通知(Email/Slack)、安全性稽核。

3. 頁面層:ErrorPage 屬性與 Page_Error

<%@ Page Language="C#" ErrorPage="~/Error/PageSpecificError.aspx" %>

protected void Page_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    if (ex is SqlException)
    {
        // 特定處理:記錄、顯示友善訊息、或轉向特定頁面
        Server.Transfer("~/Error/DbError.aspx");
    }
    // 不 ClearError,讓應用程式層再處理或顯示 customErrors
}
  • ErrorPage:宣告式、簡單、但無法取得例外物件。
  • Page_Error:可依例外型別分流、可 Server.Transfer 保留原始 URL 與例外上下文。

4. 程式碼層:try/catch/finally 與 using

try
{
    using (SqlConnection conn = new SqlConnection(connStr))
    {
        conn.Open();
        // 執行命令
    }
}
catch (SqlException ex) when (ex.Number == 2627) // 唯一鍵衝突
{
    ModelState.AddModelError("", "資料重複,請修改後重試。");
}
catch (Exception ex)
{
    _logger.Error(ex);
    throw; // 重拋讓上層處理
}

原則:只捕獲你知道如何處理的例外;其餘向上傳播。

優先順序與執行流程

  1. 程式碼 try/catch → 若捕獲並處理(不重拋),流程結束。
  2. 頁面 Page_Error → 若 Server.ClearError() 或 Server.Transfer,流程結束。
  3. 應用程式 Application_Error → 若 Server.ClearError() + Response.Redirect,流程結束。
  4. customErrors / httpErrors → 依狀態碼重導向靜態/動態錯誤頁。
  5. IIS 預設錯誤頁(最後防線)。

最佳實務架構建議

// 1. 統一例外記錄介面
public interface IExceptionLogger { void Log(Exception ex, HttpRequestBase request); }

// 2. 全域錯誤處理模組 (HttpModule) - 取代 Global.asax,更模組化
public class ErrorHandlingModule : IHttpModule
{
    private readonly IExceptionLogger _logger;
    public void Init(HttpApplication context)
    {
        context.Error += (s, e) => {
            var ex = context.Server.GetLastError().GetBaseException();
            _logger.Log(ex, new HttpRequestWrapper(context.Request));
            // 可選:context.Server.ClearError(); context.Response.Redirect(...);
        };
    }
}

// 3. 友善錯誤頁面控制器
public class ErrorController : Controller
{
    public ActionResult Index(int? statusCode, string exId) { /* 顯示對應視圖 */ }
    public ActionResult DbError() { return View(); }
    public ActionResult NotFound() { Response.StatusCode = 404; return View(); }
}

安全性考量

  • 生產環境 絕不 顯示堆疊追蹤、原始碼、連線字串給終端使用者。
  • customErrors mode="RemoteOnly" 讓本機開發者看詳細錯誤,遠端使用者看友善頁面。
  • 錯誤頁面本身不得拋出例外(避免無限迴圈),保持極簡、無外部相依。

總結

機制範圍能否記錄例外能否依例外型別處理推薦用途
try/catch區塊是是業務邏輯預期錯誤(驗證失敗、資料衝突)
Page_Error頁面是是頁面特定錯誤轉向、保留上下文
Application_Error應用程式是是集中日誌、通知、安全稽核
customErrors/httpErrors應用程式/IIS否否(僅狀態碼)最後防線、靜態檔案錯誤、無程式碼部署

組合使用四層防護,依據錯誤性質在適當層級處理,才能打造穩健、安全、使用者友善的 ASP.NET 應用程式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved