1. .NET6中全局異常處理

        共 4532字,需瀏覽 10分鐘

         ·

        2022-04-19 05:53

        微信公眾號(hào):趣編程ACE
        關(guān)注可了解每日一更的.NET日常實(shí)戰(zhàn)開(kāi)發(fā)技巧,歡迎公眾號(hào)留言開(kāi)發(fā) 獲取源碼;

        .NET6中全局異常處理

        異常處理是我們?cè)诔绦蜷_(kāi)發(fā)中不可或缺的一環(huán),下文我將會(huì)結(jié)合程序Sample講解如何在.NET6中有效處理異常。

        1. Try-Ctach 塊包裹

        2. 自定義異常中間件

        Try-Catch 塊

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

         1using?ExceptionHandling.Services;
        2using?Microsoft.AspNetCore.Mvc;
        3namespace?ExceptionHandling.Controllers;
        4
        5[ApiController]
        6[Route("api/[controller]")]
        7public?class?UserController?:?Controller
        8{
        9????private?readonly?IUserService?_userService;
        10????private?readonly?ILogger?_logger;
        11
        12????///?
        13????///?依賴注入?IUserService?ILogger
        14????///?

        15????///?
        16????///?
        17????public?UserController(IUserService?userService,?ILogger?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");?//?此處拋出一個(gè)獲取用戶出錯(cuò)異常
        34
        35???????????return?Ok(result);
        36???????}
        37???????catch?(System.Exception?e)
        38???????{
        39???????????_logger.LogError(e.Message);
        40???????????return?BadRequest("獲取失敗");?//?返回給前端
        41???????}
        42????}
        43}

        我們?cè)赩sCode里面按照一個(gè)Postman插件PostCode 調(diào)用上面接口https://localhost:7218/api/User


        通過(guò)結(jié)果可知,當(dāng)我們沒(méi)有獲取到用戶的時(shí)候,代碼將會(huì)拋出一個(gè)Get User failed的異常(見(jiàn)上圖)。對(duì)于初學(xué)者來(lái)說(shuō),這是最常見(jiàn)最基礎(chǔ)的方法,但是這個(gè)方法對(duì)于大項(xiàng)目來(lái)說(shuō)也有一個(gè)缺點(diǎn)。

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

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


        自定義中間件處理異常

        在根目錄下創(chuàng)建一個(gè)Middlewares文件夾,新建一個(gè)名為ExceptionHandlingMiddleware.cs

         1using?System.Net;
        2using?System.Text.Json;
        3using?ExceptionHandling.Models.Responses;
        4
        5namespace?ExceptionHandling.Middlewares;
        6
        7public?class?ExceptionHandlingMiddleware
        8{
        9????private?readonly?RequestDelegate?_next;??//?用來(lái)處理上下文請(qǐng)求??
        10????private?readonly?ILogger?_logger;
        11????public?ExceptionHandlingMiddleware(RequestDelegate?next,?ILogger?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);?//要么在中間件中處理,要么被傳遞到下一個(gè)中間件中去
        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????????};??//?自定義的異常錯(cuò)誤信息類型
        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中,我們首先通過(guò)依賴注入ILoggerRequestDelegate服務(wù)。委托類型_next用來(lái)處理上下文請(qǐng)求,要么將上下文放在中間件中處理,要么傳遞到下個(gè)中間鏈里的下一個(gè)中間件中去。

        如果我們的請(qǐng)求發(fā)生異常,那么就會(huì)執(zhí)行HandleExceptionAsync這個(gè)方法。這個(gè)方法里面會(huì)根據(jù)異常類型來(lái)返回不同的狀態(tài)碼并且記錄到日志中去,不需要返回給調(diào)用的客戶端,然后我們就可以通過(guò)檢查日志來(lái)發(fā)現(xiàn)異常信息。

        我們?cè)?strong style="font-size: inherit;color: inherit;line-height: inherit;">Program.cs中添加自定義異常

        1?app.UseMiddleware<ExceptionHandlingMiddleware>();

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

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

        通過(guò)調(diào)試我們可以發(fā)現(xiàn),當(dāng)發(fā)生異常的時(shí)候,程序?qū)?huì)執(zhí)行到HandleExceptionAsync()方法中去,接著根據(jù)類型KeyNotFoundException 返回404的狀態(tài)碼和異常信息。



        瀏覽 123
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 亚洲午夜色 | 艹逼免费 | 亚洲欧美精品无码成人片金桔影视 | 日日夜夜精品免费观看 | 做爱综合网|