Google Code Prettify

如何改善"未捕獲的例外異常"的發生

System.ObjectDisposedException: 'The response has been aborted due to an unhandled application exception.' 是一個通用錯誤,表示在 ASP.NET Core 應用程序中,對 HTTP 回應的處理過程中發生了異常,導致回應被中止。

以下是可能的原因及解決方法:


1. 未捕獲的例外異常

這是最常見的情況。應用程序內部發生了異常(例如空指針引用、文件未找到等),但未被處理。

解決方法

  • 確保所有異常都被正確處理,特別是在控制器中處理用戶請求的地方。
  • 使用全局異常處理中間件來捕捉未處理的異常。

範例:使用全局異常處理中間件

Program.cs 中添加以下代碼:

csharp

app.UseExceptionHandler("/Home/Error"); // 將未處理的異常重定向到特定頁面 app.UseHsts();

錯誤頁面控制器

csharp

public IActionResult Error() { var errorDetails = HttpContext.Features.Get<IExceptionHandlerPathFeature>(); // 可以記錄日誌或自定義錯誤頁面 return View(errorDetails); }

2. HTTP 回應過早完成或被中止

ASP.NET Core 偶爾會因某些未正確同步的邏輯導致異常,例如在 HTTP 請求完成後仍試圖訪問 HttpResponse 對象。

解決方法

檢查所有操作中是否存在異步操作沒有被正確 await 的情況,確保所有異步代碼都遵循正確的流程。

範例:修正錯誤的異步邏輯

錯誤的代碼:

csharp

public async Task<IActionResult> MyAction() { var task = SomeAsyncOperation(); // 未 await return Ok(); // HTTP 回應已完成 await task; // 異常發生 }

正確的代碼:

csharp

public async Task<IActionResult> MyAction() { await SomeAsyncOperation(); // 確保異步操作完成 return Ok(); }

3. 部分視圖或視圖渲染失敗

如果您正在渲染部分視圖或完整視圖,異常可能發生在視圖中,例如模型為空或類型不匹配。

解決方法

檢查視圖的模型是否正確,並在控制器中使用 try-catch 捕獲可能的異常。

範例:捕獲視圖異常

csharp

try { return PartialView("_MyPartial", model); } catch (Exception ex) { // 記錄異常日誌 return StatusCode(500, "部分視圖渲染失敗"); }

4. 資源被提前釋放

在 ASP.NET Core 中,某些異常可能由於 HttpContextHttpResponse 被過早釋放而引發。

解決方法

確保在異步操作中不會過早釋放資源,並且任何與 HttpContextHttpResponse 相關的操作都在請求上下文內執行。

範例:正確使用 HttpContext

錯誤的代碼:

csharp

public async Task<IActionResult> MyAction() { var response = HttpContext.Response; // 在請求上下文結束後仍嘗試操作 response await Task.Delay(1000); response.WriteAsync("Hello"); // 可能導致異常 return Ok(); }

正確的代碼:

csharp

public async Task<IActionResult> MyAction() { await HttpContext.Response.WriteAsync("Hello"); return Ok(); }

5. 中間件配置問題

如果您使用自定義中間件,可能未正確處理 next 或異常。

解決方法

檢查所有自定義中間件是否正確地調用了 await next(context)

範例:正確的中間件設置

csharp

public class MyMiddleware { private readonly RequestDelegate _next; public MyMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { try { await _next(context); } catch (Exception ex) { // 捕捉異常並處理 await context.Response.WriteAsync("中間件異常處理"); } } }

6. 日誌記錄

為了確定具體的錯誤原因,建議啟用詳細的日誌記錄。

appsettings.json 中啟用詳細日誌:

json

{ "Logging": { "LogLevel": { "Default": "Debug", "Microsoft": "Warning" } } }

7. 總結

要解決 System.ObjectDisposedException 錯誤,請採取以下步驟:

  1. 確保代碼邏輯中異常被正確捕獲。
  2. 確認異步操作是否正確 await
  3. 檢查模型與視圖是否匹配。
  4. 測試和驗證中間件的執行流程。
  5. 啟用日誌記錄以追蹤問題源頭。