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

ASP.NET Runtime Error (執行階段錯誤) 成因分析與解決方案:自訂錯誤頁面、詳細錯誤開啟、ASP.NET 註冊修復

     編輯:ASP.NET 基礎

錯誤畫面解讀

Runtime Error
Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.

**核心含義**:應用程式發生未處理例外,但 `web.config` 設定 `` (預設),導致遠端瀏覽器看不到詳細錯誤堆疊,只見通用錯誤頁。

立即解決:開啟詳細錯誤訊息 (僅限開發/測試環境)

<!-- web.config -->
<configuration>
  <system.web>
    <!-- mode="Off":所有環境顯示詳細錯誤 (含堆疊) -->
    <customErrors mode="Off" />
  </system.web>
</configuration>

重新整理頁面,即可看到完整 **黃色死機畫面 (YSOD)**,包含例外類型、訊息、堆疊追蹤、原始碼行號。

生產環境正確做法:自訂錯誤頁面 + 記錄日誌

<configuration>
  <system.web>
    <customErrors mode="RemoteOnly" defaultRedirect="~/Error/General.aspx">
      <error statusCode="404" redirect="~/Error/404.aspx" />
      <error statusCode="500" redirect="~/Error/500.aspx" />
    </customErrors>
  </system.web>
</configuration>
  • `mode="RemoteOnly"`:本機看詳細錯誤,遠端看自訂頁面。
  • `defaultRedirect`:未指定狀態碼的錯誤導向頁。
  • ``:特定 HTTP 狀態碼導向專屬頁面。

自訂錯誤頁面範例

<!-- Error/500.aspx -->
<%@ Page Language="C#" %>
<!DOCTYPE html>
<html>
<head><title>系統錯誤</title></head>
<body>
    <h1>抱歉,系統發生錯誤 (500)</h1>
    <p>我們已記錄此錯誤,技術人員會盡快處理。</p>
    <p><a href="/">返回首頁</a></p>
    <!-- 可選:顯示錯誤參考代碼 (從 Session/QueryString 取得) -->
    <% if (Request.QueryString["errId"] != null) { %>
        <p>錯誤參考代碼:<%= Request.QueryString["errId"] %></p>
    <% } %>
</body>
</html>

全域例外攔截與記錄

// Global.asax.cs
protected void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    
    // 1. 記錄完整堆疊至 Log (log4net / NLog / Serilog / Enterprise Library)
    Logger.Error(ex, "Unhandled exception");
    
    // 2. 取得 HttpException 狀態碼
    var httpEx = ex as HttpException;
    int statusCode = httpEx?.GetHttpCode() ?? 500;
    
    // 3. 清除錯誤,避免預設處理
    Server.ClearError();
    
    // 4. 導向對應錯誤頁 (帶上錯誤 ID 供查詢)
    string errorId = Guid.NewGuid().ToString("N").Substring(0, 8);
    Response.Redirect($"~/Error/{statusCode}.aspx?errId={errorId}");
}

根本原因深度排查:常見導致 Runtime Error 的情境

類別典型原因排查方向
設定錯誤web.config 格式錯誤、區段重複、權限不足讀取設定檢查 Event Viewer → Application → ASP.NET 事件;啟用 `` 看 YSOD
編譯錯誤.aspx/.cshtml 語法錯誤、缺少命名空間、型別不符YSOD 會直接顯示編譯錯誤行號
資料庫連線連線字串錯誤、SQL Server 未啟動、防火牆、權限不足、連線池耗盡檢查連線字串、SQL Log、連線池大小設定
Null 參考Session/ViewState 為 null、資料庫查無資料直接 .ToString()、物件未初始化堆疊追蹤定位行號,加入防禦性檢查 `?.` / `??`
權限/信任檔案寫入無權限、登錄存取拒絕、Medium Trust 限制、CAS 政策檢查應用程式池身分 (ApplicationPoolIdentity) 資料夾權限
第三方元件DLL 版本衝突 (DLL Hell)、缺少相依組件、授權過期、非托管記憶體洩漏Fusion Log (fuslogvw) 追蹤組件載入失敗
ASP.NET 未正確註冊至 IIS安裝 .NET 後未執行 `aspnet_regiis -i`、IIS 版本不匹配、應用程式池 .NET 版本錯誤見下方修復步驟

經典修復:ASP.NET 註冊至 IIS (aspnet_regiis.exe)

**適用情境**:安裝 .NET Framework 後、安裝/升級 IIS 後、手動刪除 IIS 註冊腳本後、應用程式池顯示「未識別的 Managed 版本」。

指令 (需以管理員身分執行 CMD/PowerShell)

REM .NET Framework 2.0 / 3.5 (經典模式)
C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -i
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\aspnet_regiis.exe -i

REM .NET Framework 4.x (整合模式)
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i

REM .NET Framework 4.6.2+ / Windows 10 / Server 2016+ (建議用 DISM)
dism /online /enable-feature /featurename:IIS-ASPNET45 /all
dism /online /enable-feature /featurename:IIS-ASPNET /all

REM 驗證註冊結果
aspnet_regiis.exe -lv
-- 輸出應包含版本號與 "Installed" 狀態

IIS 設定檢查清單

  • 應用程式池 → **.NET CLR 版本** = `v4.0` (對應 .NET 4.x) 或 `v2.0` (對應 .NET 2.0/3.5)。
  • 應用程式池 → **受控管線模式** = `Integrated` (現代) 或 `Classic` (舊版相容)。
  • 網站 → **基本設定** → 應用程式池選擇正確。
  • 處理常式對應 → 確認 `*.aspx`、`*.ashx`、`*.asmx` 映射至 `System.Web.HttpForbiddenHandler` / `PageHandlerFactory` 等。

進階診斷工具

  • Failed Request Tracing (FREB):IIS → 網站 → 失敗的要求追蹤 → 啟用狀態碼 500 → 產生詳細 XML 日誌,含模組、通知、處理常式、耗時、錯誤代碼。
  • Event Viewer → Windows Logs → Application:來源 `ASP.NET 4.0.30319.0` / `.NET Runtime`,含例外類型、訊息、堆疊、進程 ID。
  • DebugDiag / ProcDump:擷取記憶體傾印分析 Crash/Hang/記憶體洩漏。
  • fuslogvw.exe (Assembly Binding Log Viewer):診斷組件載入失敗 (版本衝突、缺檔)。

總結:標準處理流程

  1. **開啟詳細錯誤** (`customErrors mode="Off"`) → 取得 YSOD 堆疊。
  2. **依堆疊定位代碼行** → 修正邏輯/Null 檢查/設定。
  3. **若為環境問題** (ASP.NET 未註冊、權限、組件衝突) → 執行 `aspnet_regiis -i` / 授權 / 重裝套件。
  4. **生產環境關閉詳細錯誤** → 設定 `RemoteOnly` + 自訂錯誤頁 + `Application_Error` 記錄日誌。
  5. **建立監控告警**:Log 錯誤率突增 → 通知開發團隊。

核心心法:**Runtime Error 只是遮罩,YSOD 才是真相;環境問題靠註冊修復,代碼問題靠堆疊定位;生產環境永遠不顯示堆疊給使用者。**

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