.Net Core2.2異常處理
阿新 • • 發佈:2020-09-13
初始化新的專案,在Configure的第一行可以看到如下程式碼:
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); }
程式碼使用 IsDevelopment() 判斷了當前是否為開發者模式,然後通過UseDeveloperExceptionPage() 就跳轉到了堆疊錯誤頁面。當然,正式環境的時候可不能這樣,所以用UseExceptionHandler() 這個預設錯誤處理方法,跳轉到了錯誤提示頁面,UseExceptionHandler() 還有一個過載方法使用lambda 表示式來處理異常:
app.UseExceptionHandler(errorApp => { errorApp.Run(async context => { context.Response.StatusCode = 500; context.Response.ContentType = "text/html"; await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n"); await context.Response.WriteAsync("ERROR!<br><br>\r\n"); }); });
一、異常過濾器
建立我們自己的異常過濾器需要繼承IAsyncExceptionFilter ,然後實現 OnExceptionAsync 方法對錯誤資訊進行處理:
public class MyCustomerExceptionFilter : IAsyncExceptionFilter { public Task OnExceptionAsync(ExceptionContext context) { if (context.ExceptionHandled == false) { string msg = context.Exception.Message; context.Result = new ContentResult { Content = msg, StatusCode = StatusCodes.Status200OK, ContentType = "text/html;charset=utf-8" }; } context.ExceptionHandled = true; //異常已處理了 return Task.CompletedTask; } }
這裡將 context.ExceptionHandled 設定為了true,表示該異常已經被處理,後續的異常處理的中介軟體也不會再重複處理這個異常了。最後在 Startup.cs 中加入它就可以看:
services.AddControllers(options => options.Filters.Add(new MyCustomerExceptionFilter()));
二、異常中介軟體
異常中介軟體和異常過濾器的區別就是,異常中介軟體的範圍更廣,異常過濾器只能處理mvc中發生的錯誤,而中介軟體可以捕獲其之後的所有異常。如下:
public class MyExceptionMiddleware { private readonly RequestDelegate _next; public MyExceptionMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext httpContext) { try { await _next(httpContext); } catch (Exception ex) { httpContext.Response.ContentType = "application/problem+json"; var title = "An error occured: " + ex.Message; var details = ex.ToString(); var problem = new ProblemDetails { Status = 200, Title = title, Detail = details }; //Serialize the problem details object to the Response as JSON (using System.Text.Json) var stream = httpContext.Response.Body; await JsonSerializer.SerializeAsync(stream, problem); } } }
app.UseMiddleware<MyExceptionMiddleware>();
不過這樣也沒啥必要,因為UseExceptionHandler 的過載方法也可以實現,最開始的時候已經給出了。