asp.net core中的異常處理


開發人員異常頁

開發人員異常頁 顯示請求異常的詳細信息。 此頁是通過 Microsoft.AspNetCore.App 元包中的 Microsoft.AspNetCore.Diagnostics 包提供。 向 Startup.Configure 方法添加代碼,以當應用在開發環境中運行時啟用此頁:

1 if (env.IsDevelopment())
2 {
3     app.UseDeveloperExceptionPage();
4 }
5 else
6 {
7     app.UseExceptionHandler("/Error");
8     app.UseHsts();
9 }

 

將 UseDeveloperExceptionPage 調用置於要捕獲其異常的任何中間件前面。

 警告

僅當應用程序在開發環境中運行時才啟用開發人員異常頁 。 否則當應用程序在生產環境中運行時,詳細的異常信息會向公眾泄露 有關配置環境的詳細信息,請參閱 在 ASP.NET Core 中使用多個環境

該頁包括關於異常和請求的以下信息:

  • 堆棧跟蹤
  • 查詢字符串參數(如果有)
  • Cookie(如果有)
  • 標頭

異常處理程序頁

若要為生產環境配置自定義錯誤處理頁,請使用異常處理中間件。 中間件:

  • 捕獲並記錄異常。
  • 在備用管道中為指定的頁或控制器重新執行請求。 如果響應已啟動,則不會重新執行請求。

在下面的示例中,UseExceptionHandler 在非開發環境中添加異常處理中間件:

1 if (env.IsDevelopment())
2 {
3     app.UseDeveloperExceptionPage();
4 }
5 else
6 {
7     app.UseExceptionHandler("/Error");
8     app.UseHsts();
9 }

Razor Pages 應用模板提供“頁面” 文件夾中的 Error 頁 (.cshtml ) 和 PageModel 類 (ErrorModel)。 對於 MVC 應用,項目模板包括 Error 操作方法和 Error 視圖。 操作方法如下:

1 [AllowAnonymous]
2 public IActionResult Error()
3 {
4     return View(new ErrorViewModel 
5         { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
6 }
不要使用 HTTP 方法屬性(如 HttpGet)修飾錯誤處理程序操作方法。 顯式謂詞可阻止某些請求訪問方法。 允許匿名訪問方法,以便未經身份驗證的用戶能夠接收錯誤視圖。

訪問異常

使用 IExceptionHandlerPathFeature 訪問錯誤處理程序控制器或頁中的異常和原始請求路徑:

 1 var exceptionHandlerPathFeature =
 2     HttpContext.Features.Get<IExceptionHandlerPathFeature>();
 3 if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
 4 {
 5     ExceptionMessage = "File error thrown";
 6 }
 7 if (exceptionHandlerPathFeature?.Path == "/index")
 8 {
 9     ExceptionMessage += " from home page";
10 }

 警告

請勿 向客戶端提供敏感錯誤信息。 提供服務的錯誤是一種安全風險。

異常處理程序 lambda

自定義異常處理程序頁的替代方法是向 UseExceptionHandler 提供 lambda。 使用 lambda,可以在返回響應前訪問錯誤。

下面的示例展示了如何使用 lambda 進行異常處理:

 1 if (env.IsDevelopment())
 2 {
 3     app.UseDeveloperExceptionPage();
 4 }
 5 else
 6 {
 7    app.UseExceptionHandler(errorApp =>
 8    {
 9         errorApp.Run(async context =>
10         {
11             context.Response.StatusCode = 500;
12             context.Response.ContentType = "text/html";
13 
14             await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
15             await context.Response.WriteAsync("ERROR!<br><br>\r\n");
16 
17             var exceptionHandlerPathFeature = 
18                 context.Features.Get<IExceptionHandlerPathFeature>();
19 
20             // Use exceptionHandlerPathFeature to process the exception (for example, 
21             // logging), but do NOT expose sensitive error information directly to 
22             // the client.
23 
24             if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
25             {
26                 await context.Response.WriteAsync("File error thrown!<br><br>\r\n");
27             }
28 
29             await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n");
30             await context.Response.WriteAsync("</body></html>\r\n");
31             await context.Response.WriteAsync(new string(' ', 512)); // IE padding
32         });
33     });
34     app.UseHsts();
35 }

 警告

不要 向客戶端提供來自 IExceptionHandlerFeature 或 IExceptionHandlerPathFeature 的敏感錯誤信息。 提供服務的錯誤是一種安全風險。

 

UseStatusCodePages

默認情況下,ASP.NET Core 應用不會為 HTTP 狀態代碼(如“404 - 未找到” )提供狀態代碼頁。 應用返回狀態代碼和空響應正文。 若要提供狀態代碼頁,請使用狀態代碼頁中間件。

此中間件是通過 Microsoft.AspNetCore.App 元包中的 Microsoft.AspNetCore.Diagnostics 包提供。

若要啟用常見錯誤狀態代碼的默認純文本處理程序,請在 Startup.Configure 方法中調用 UseStatusCodePages

 app.UseStatusCodePages(); 

在請求處理中間件(例如,靜態文件中間件和 MVC 中間件)前面調用 UseStatusCodePages

下面的示例展示了默認處理程序顯示的文本:

 Status Code: 404; Not Found 

 

包含格式字符串的 UseStatusCodePages

若要自定義響應內容類型和文本,請利用需要使用內容類型和格式字符串的 UseStatusCodePages 重載:

 app.UseStatusCodePages( "text/plain", "Status code page, status code: {0}");  

包含 lambda 的 UseStatusCodePages

若要指定自定義錯誤處理和響應寫入代碼,請利用需要使用 lambda 表達式的 UseStatusCodePages 重載:

1 app.UseStatusCodePages(async context =>
2 {
3     context.HttpContext.Response.ContentType = "text/plain";
4 
5     await context.HttpContext.Response.WriteAsync(
6         "Status code page, status code: " + 
7         context.HttpContext.Response.StatusCode);
8 });

 


UseStatusCodePagesWithRedirects

UseStatusCodePagesWithRedirects 擴展方法:

  • 向客戶端發送“302 - 已找到” 狀態代碼。
  • 將客戶端重定向到 URL 模板中的位置。
 app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}"); 

URL 模板可能會包括狀態代碼的 {0} 占位符,如上面的示例所示。 如果 URL 模板以波形符 (~) 開頭,波形符會替換為應用的 PathBase。 如果在應用中指向終結點,請為終結點創建 MVC 視圖或 Razor 頁面。 有關 Razor Pages 示例,請參閱示例應用中的 Pages/StatusCode.cshtml 。

使用此方法通常是當應用:

  • 應將客戶端重定向到不同的終結點(通常在不同的應用處理錯誤的情況下)。 對於 Web 應用,客戶端的瀏覽器地址欄反映重定向終結點。
  • 不應保留原始狀態代碼並通過初始重定向響應返回該代碼。

UseStatusCodePagesWithReExecute

UseStatusCodePagesWithReExecute 擴展方法:

  • 向客戶端返回原始狀態代碼。
  • 通過使用備用路徑重新執行請求管道,從而生成響應正文。
 app.UseStatusCodePagesWithReExecute("/StatusCode","?code={0}"); 

如果在應用中指向終結點,請為終結點創建 MVC 視圖或 Razor 頁面。 有關 Razor Pages 示例,請參閱示例應用中的 Pages/StatusCode.cshtml 。

使用此方法通常是當應用應:

  • 處理請求,但不重定向到不同終結點。 對於 Web 應用,客戶端的瀏覽器地址欄反映最初請求的終結點。
  • 保留原始狀態代碼並通過響應返回該代碼。

URL 模板和查詢字符串模板可能包括狀態代碼的占位符 ({0})。 URL 模板必須以斜杠 (/) 開頭。 若要在路徑中使用占位符,請確認終結點(頁或控制器)能否處理路徑段。 例如,錯誤的 Razor Page 應通過 @page 指令接受可選路徑段值:

 @page "{code?}" 

錯誤處理終結點可以獲取生成錯誤的原始 URL,如下面的示例所示:

1 var statusCodeReExecuteFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
2 if (statusCodeReExecuteFeature != null)
3 {
4     OriginalURL =
5         statusCodeReExecuteFeature.OriginalPathBase
6         + statusCodeReExecuteFeature.OriginalPath
7         + statusCodeReExecuteFeature.OriginalQueryString;
8 }

 

禁用狀態代碼頁

若要禁用 MVC 控制器或操作方法的狀態代碼頁,請使用 [SkipStatusCodePages] 特性。

若要禁用 Razor Pages 處理程序方法或 MVC 控制器中的特定請求的狀態代碼頁,請使用 IStatusCodePagesFeature

1 var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();
2 
3 if (statusCodePagesFeature != null)
4 {
5     statusCodePagesFeature.Enabled = false;
6 }

 

異常處理代碼

異常處理頁中的代碼可能會引發異常。 建議在生產錯誤頁面中包含純靜態內容。

響應頭

在響應頭發送后:

  • 應用無法更改響應的狀態代碼。
  • 任何異常頁或處理程序都無法運行。 必須完成響應或中止連接。

服務器異常處理

除了應用中的異常處理邏輯外,HTTP 服務器實現還能處理一些異常。 如果服務器在發送響應標頭之前捕獲到異常,服務器將發送不包含響應正文的“500 - 內部服務器錯誤” 響應。 如果服務器在發送響應標頭后捕獲到異常,服務器會關閉連接。 應用程序無法處理的請求將由服務器進行處理。 當服務器處理請求時,發生的任何異常都將由服務器的異常處理進行處理。 應用的自定義錯誤頁面、異常處理中間件和篩選器都不會影響此行為。

啟動異常處理

應用程序啟動期間發生的異常僅可在承載層進行處理。 可以將主機配置為,捕獲啟動錯誤捕獲詳細錯誤

僅當錯誤在主機地址/端口綁定后出現時,托管層才能顯示捕獲的啟動錯誤的錯誤頁。 如果綁定失敗:

  • 托管層將記錄關鍵異常。
  • dotnet 進程崩潰。
  • 不會在 HTTP 服務器為 Kestrel 時顯示任何錯誤頁。

在 IIS(或 Azure 應用服務)或 IIS Express 上運行應用時,如果無法啟動進程,ASP.NET Core 模塊將返回“502.5 - 進程失敗” 。 有關詳細信息,請參閱 Azure App Service 和 IIS 上的 ASP.NET Core 疑難解答

數據庫錯誤頁

數據庫錯誤頁中間件捕獲與數據庫相關的異常,可使用實體框架遷移來解析這些異常。 當這些異常出現時,便會生成 HTML 響應,其中包含用於解決問題的可能操作的詳細信息。 應僅在開發環境中啟用此頁。 通過向 Startup.Configure 添加代碼來啟用此頁:

1 if (env.IsDevelopment())
2 {
3     app.UseDatabaseErrorPage();
4 }

 

異常篩選器

在 MVC 應用中,可以全局配置異常篩選器,也可以為每個控制器或每個操作單獨配置。 在 Razor Pages 應用中,可以全局配置異常篩選器,也可以為每個頁面模型單獨配置。 這些篩選器處理在執行控制器操作或其他篩選器時出現的任何未處理的異常。 有關詳細信息,請參閱 ASP.NET Core 中的篩選器

 提示

異常篩選器適合捕獲 MVC 操作內發生的異常,但它們不如異常處理中間件靈活。 建議使用中間件。 僅在需要根據選定 MVC 操作以不同方式執行錯誤處理時,才使用篩選器。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM