日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

【C#/.NET】.NET6中全局异常处理

發布時間:2023/12/4 C# 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C#/.NET】.NET6中全局异常处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

微信公眾號:趣編程ACE
關注可了解每日一更的.NET日常實戰開發技巧,歡迎公眾號留言開發 獲取源碼;

.NET6中全局異常處理

異常處理是我們在程序開發中不可或缺的一環,下文我將會結合程序Sample講解如何在.NET6中有效處理異常。

  • Try-Ctach 塊包裹

  • 自定義異常中間件

  • Try-Catch 塊

    Try-Catch 是最基本的異常處理方法,下面我們看下例子。
    創建一個基于.net6的Asp.Net Core Web Api項目

    1using?ExceptionHandling.Services;2using?Microsoft.AspNetCore.Mvc;3namespace?ExceptionHandling.Controllers;45[ApiController]6[Route("api/[controller]")]7public?class?UserController?:?Controller8{9????private?readonly?IUserService?_userService; 10????private?readonly?ILogger<UserController>?_logger; 11 12????///?<summary> 13????///?依賴注入?IUserService?ILogger<UserController> 14????///?</summary> 15????///?<param?name="userService"></param> 16????///?<param?name="logger"></param> 17????public?UserController(IUserService?userService,?ILogger<UserController>?logger) 18????{ 19????????_userService?=?userService; 20????????_logger?=?logger; 21????} 22 23????[HttpGet] 24????public?IActionResult?GetUsers() 25????{ 26 27???????try 28???????{ 29???????????_logger.LogInformation("Get?User?Details"); 30 31???????????var?result?=?_userService.GetUsers(); 32???????????if(result.Count==0) 33????????????throw?new?ApplicationException("Get?User?failed");?//?此處拋出一個獲取用戶出錯異常 34 35???????????return?Ok(result); 36???????} 37???????catch?(System.Exception?e) 38???????{ 39???????????_logger.LogError(e.Message); 40???????????return?BadRequest("獲取失敗");?//?返回給前端 41???????} 42????} 43}

    我們在VsCode里面按照一個Postman插件PostCode 調用上面接口https://localhost:7218/api/User

    通過結果可知,當我們沒有獲取到用戶的時候,代碼將會拋出一個Get User failed的異常(見上圖)。對于初學者來說,這是最常見最基礎的方法,但是這個方法對于大項目來說也有一個缺點。

    如果項目中有許多控制器和動作方法,然后我們需要對每一個動作方法都使用try-catch,那么在這種情況下,用try-catch就很累贅,也會增加代碼行數。此時就需要自定義一個處理全局異常的中間件啦!

    使用這個方法的好處就是我們可以在一個地方捕獲未處理的異常,而不需要在每個動作方法中使用try-catch。

    自定義中間件處理異常

    在根目錄下創建一個Middlewares文件夾,新建一個名為ExceptionHandlingMiddleware.cs類

    1using?System.Net;2using?System.Text.Json;3using?ExceptionHandling.Models.Responses;45namespace?ExceptionHandling.Middlewares;67public?class?ExceptionHandlingMiddleware8{9????private?readonly?RequestDelegate?_next;??//?用來處理上下文請求?? 10????private?readonly?ILogger<ExceptionHandlingMiddleware>?_logger; 11????public?ExceptionHandlingMiddleware(RequestDelegate?next,?ILogger<ExceptionHandlingMiddleware>?logger) 12????{ 13????????_next?=?next; 14????????_logger?=?logger; 15????} 16 17????public?async?Task?InvokeAsync(HttpContext?httpContext) 18????{ 19????????try 20????????{ 21????????????await?_next(httpContext);?//要么在中間件中處理,要么被傳遞到下一個中間件中去 22????????} 23????????catch?(Exception?ex) 24????????{ 25????????????await?HandleExceptionAsync(httpContext,?ex);?//?捕獲異常了?在HandleExceptionAsync中處理 26????????} 27????} 28????private?async?Task?HandleExceptionAsync(HttpContext?context,?Exception?exception) 29????{ 30????????context.Response.ContentType?=?"application/json";??//?返回json?類型 31????????var?response?=?context.Response; 32 33????????var?errorResponse?=?new?ErrorResponse 34????????{ 35????????????Success?=?false 36????????};??//?自定義的異常錯誤信息類型 37????????switch?(exception) 38????????{ 39????????????case?ApplicationException?ex: 40????????????????if?(ex.Message.Contains("Invalid?token")) 41????????????????{ 42????????????????????response.StatusCode?=?(int)?HttpStatusCode.Forbidden; 43????????????????????errorResponse.Message?=?ex.Message; 44????????????????????break; 45????????????????} 46????????????????response.StatusCode?=?(int)?HttpStatusCode.BadRequest; 47????????????????errorResponse.Message?=?ex.Message; 48????????????????break; 49????????????case?KeyNotFoundException?ex: 50????????????????response.StatusCode?=?(int)?HttpStatusCode.NotFound; 51????????????????errorResponse.Message?=?ex.Message; 52????????????????break; 53????????????default: 54????????????????response.StatusCode?=?(int)?HttpStatusCode.InternalServerError; 55????????????????errorResponse.Message?=?"Internal?Server?errors.?Check?Logs!"; 56????????????????break; 57????????} 58????????_logger.LogError(exception.Message); 59????????var?result?=?JsonSerializer.Serialize(errorResponse); 60????????await?context.Response.WriteAsync(result); 61????} 62}

    這就是我們自定義的中間件,在ExceptionHandlingMiddleware中,我們首先通過依賴注入ILogger和RequestDelegate服務。委托類型_next用來處理上下文請求,要么將上下文放在中間件中處理,要么傳遞到下個中間鏈里的下一個中間件中去。

    如果我們的請求發生異常,那么就會執行HandleExceptionAsync這個方法。這個方法里面會根據異常類型來返回不同的狀態碼并且記錄到日志中去,不需要返回給調用的客戶端,然后我們就可以通過檢查日志來發現異常信息。

    我們在Program.cs中添加自定義異常

    1?app.UseMiddleware<ExceptionHandlingMiddleware>();

    接著我們修改下控制器里GetUsers()這個方法,去掉try-catch,直接拋出異常

    1[HttpGet]2????public?IActionResult?GetUsers()3????{45??????_logger.LogInformation("Get?User?Details");67???????????var?result?=?_userService.GetUsers();8???????????if(result.Count==0)9????????????throw?new?KeyNotFoundException("Get?User?failed");?//?此處拋出一個KeyNotFoundException異常 10 11???????????return?Ok(result); 12????}

    通過調試我們可以發現,當發生異常的時候,程序將會執行到HandleExceptionAsync()方法中去,接著根據類型KeyNotFoundException 返回404的狀態碼和異常信息。


    如需理解中間件管道執行過程可參考上篇文章:【C#/.NET】控制臺上動態構建中間件管道

    總結

    以上是生活随笔為你收集整理的【C#/.NET】.NET6中全局异常处理的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。