<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        ASP.NET CORE學(xué)習(xí)教程之自定義異常處理詳解

        來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:34:40
        文檔

        ASP.NET CORE學(xué)習(xí)教程之自定義異常處理詳解

        ASP.NET CORE學(xué)習(xí)教程之自定義異常處理詳解:為什么異常處理選擇中間件? 傳統(tǒng)的ASP.NET可以采用異常過濾器的方式處理異常,在ASP.NET CORE中,是以多個(gè)中間件連接而成的管道形式處理請求的,不過常用的五大過濾器得以保留,同樣可以采用異常過濾器處理異常,但是異常過濾器不能處理MVC中間件以外的異
        推薦度:
        導(dǎo)讀ASP.NET CORE學(xué)習(xí)教程之自定義異常處理詳解:為什么異常處理選擇中間件? 傳統(tǒng)的ASP.NET可以采用異常過濾器的方式處理異常,在ASP.NET CORE中,是以多個(gè)中間件連接而成的管道形式處理請求的,不過常用的五大過濾器得以保留,同樣可以采用異常過濾器處理異常,但是異常過濾器不能處理MVC中間件以外的異

        為什么異常處理選擇中間件?

        傳統(tǒng)的ASP.NET可以采用異常過濾器的方式處理異常,在ASP.NET CORE中,是以多個(gè)中間件連接而成的管道形式處理請求的,不過常用的五大過濾器得以保留,同樣可以采用異常過濾器處理異常,但是異常過濾器不能處理MVC中間件以外的異常,為了全局統(tǒng)一考慮,采用中間件處理異常更為合適

        為什么選擇自定義異常中間件?

        先來看看ASP.NET CORE 內(nèi)置的三個(gè)異常處理中間件 DeveloperExceptionPageMiddleware, ExceptionHandlerMiddleware,StatusCodePagesMiddleware

        1.DeveloperExceptionPageMiddleware

        能給出詳細(xì)的請求/返回/錯(cuò)誤信息,因?yàn)榘舾行畔ⅲ詢H適合開發(fā)環(huán)境

        2.ExceptionHandlerMiddleware (蔣神博客:https://www.gxlcms.com/article/153926.htm)

        僅處理500錯(cuò)誤

        3.StatusCodePagesMiddleware (蔣神博客:https://www.gxlcms.com/article/153931.htm)

        能處理400-599之間的錯(cuò)誤,但需要Response中不能包含內(nèi)容(ContentLength=0 && ContentType=null,經(jīng)實(shí)驗(yàn)不能響應(yīng)mvc里未捕獲異常)

        由于ExceptionHandlerMiddleware和StatusCodePagesMiddleware的各自的限制條件,兩者需要搭配使用。相比之下自定義中間件更加靈活,既能對各種錯(cuò)誤狀態(tài)進(jìn)行統(tǒng)一處理,也能按照配置決定處理方式。

        CustomExceptionMiddleWare

        首先聲明異常中間件的配置類

        /// <summary>
         /// 異常中間件配置對象
         /// </summary>
         public class CustomExceptionMiddleWareOption
         {
         public CustomExceptionMiddleWareOption(
         CustomExceptionHandleType handleType = CustomExceptionHandleType.JsonHandle,
         IList<PathString> jsonHandleUrlKeys = null,
         string errorHandingPath = "")
         {
         HandleType = handleType;
         JsonHandleUrlKeys = jsonHandleUrlKeys;
         ErrorHandingPath = errorHandingPath;
         }
        
         /// <summary>
         /// 異常處理方式
         /// </summary>
         public CustomExceptionHandleType HandleType { get; set; }
        
         /// <summary>
         /// Json處理方式的Url關(guān)鍵字
         /// <para>僅HandleType=Both時(shí)生效</para>
         /// </summary>
         public IList<PathString> JsonHandleUrlKeys { get; set; }
        
         /// <summary>
         /// 錯(cuò)誤跳轉(zhuǎn)頁面
         /// </summary>
         public PathString ErrorHandingPath { get; set; }
         }
        
         /// <summary>
         /// 錯(cuò)誤處理方式
         /// </summary>
         public enum CustomExceptionHandleType
         {
         JsonHandle = 0, //Json形式處理
         PageHandle = 1, //跳轉(zhuǎn)網(wǎng)頁處理
         Both = 2 //根據(jù)Url關(guān)鍵字自動(dòng)處理
         }

        聲明異常中間件的成員

        /// <summary>
         /// 管道請求委托
         /// </summary>
         private RequestDelegate _next;
        
         /// <summary>
         /// 配置對象
         /// </summary>
         private CustomExceptionMiddleWareOption _option;
        
         /// <summary>
         /// 需要處理的狀態(tài)碼字典
         /// </summary>
         private IDictionary<int, string> exceptionStatusCodeDic;
        
         public CustomExceptionMiddleWare(RequestDelegate next, CustomExceptionMiddleWareOption option)
         {
         _next = next;
         _option = option;
         exceptionStatusCodeDic = new Dictionary<int, string>
         {
         { 401, "未授權(quán)的請求" },
         { 404, "找不到該頁面" },
         { 403, "訪問被拒絕" },
         { 500, "服務(wù)器發(fā)生意外的錯(cuò)誤" }
         //其余狀態(tài)自行擴(kuò)展
         };
         }

        異常中間件主要邏輯

        public async Task Invoke(HttpContext context)
         {
         Exception exception = null;
         try
         {
         await _next(context); //調(diào)用管道執(zhí)行下一個(gè)中間件
         }
         catch (Exception ex)
         {
         context.Response.Clear(); 
         context.Response.StatusCode = 500; //發(fā)生未捕獲的異常,手動(dòng)設(shè)置狀態(tài)碼
         exception = ex;
         }
         finally
         {
         if (exceptionStatusCodeDic.ContainsKey(context.Response.StatusCode) && 
         !context.Items.ContainsKey("ExceptionHandled")) //預(yù)處理標(biāo)記
         {
         var errorMsg = string.Empty;
         if (context.Response.StatusCode == 500 && exception != null)
         {
         errorMsg = $"{exceptionStatusCodeDic[context.Response.StatusCode]}\r\n{(exception.InnerException != null ? exception.InnerException.Message : exception.Message)}";
         }
         else
         {
         errorMsg = exceptionStatusCodeDic[context.Response.StatusCode];
         }
         exception = new Exception(errorMsg);
         }
        
         if (exception != null)
         {
         var handleType = _option.HandleType;
         if (handleType == CustomExceptionHandleType.Both) //根據(jù)Url關(guān)鍵字決定異常處理方式
         {
         var requestPath = context.Request.Path;
         handleType = _option.JsonHandleUrlKeys != null && _option.JsonHandleUrlKeys.Count(
         k => context.Request.Path.StartsWithSegments(k, StringComparison.CurrentCultureIgnoreCase)) > 0 ?
         CustomExceptionHandleType.JsonHandle :
         CustomExceptionHandleType.PageHandle;
         }
         
         if (handleType == CustomExceptionHandleType.JsonHandle)
         await JsonHandle(context, exception);
         else
         await PageHandle(context, exception, _option.ErrorHandingPath);
         }
         }
         }
        
         /// <summary>
         /// 統(tǒng)一格式響應(yīng)類
         /// </summary>
         /// <param name="ex"></param>
         /// <returns></returns>
         private ApiResponse GetApiResponse(Exception ex)
         {
         return new ApiResponse() { IsSuccess = false, Message = ex.Message };
         }
        
         /// <summary>
         /// 處理方式:返回Json格式
         /// </summary>
         /// <param name="context"></param>
         /// <param name="ex"></param>
         /// <returns></returns>
         private async Task JsonHandle(HttpContext context, Exception ex)
         {
         var apiResponse = GetApiResponse(ex);
         var serialzeStr = JsonConvert.SerializeObject(apiResponse);
         context.Response.ContentType = "application/json";
         await context.Response.WriteAsync(serialzeStr, Encoding.UTF8);
         }
        
         /// <summary>
         /// 處理方式:跳轉(zhuǎn)網(wǎng)頁
         /// </summary>
         /// <param name="context"></param>
         /// <param name="ex"></param>
         /// <param name="path"></param>
         /// <returns></returns>
         private async Task PageHandle(HttpContext context, Exception ex, PathString path)
         {
         context.Items.Add("Exception", ex);
         var originPath = context.Request.Path;
         context.Request.Path = path; //設(shè)置請求頁面為錯(cuò)誤跳轉(zhuǎn)頁面
         try
         {
         await _next(context); 
         }
         catch { }
         finally
         {
         context.Request.Path = originPath; //恢復(fù)原始請求頁面
         }
         }

        使用擴(kuò)展類進(jìn)行中間件注冊

        public static class CustomExceptionMiddleWareExtensions
         {
        
         public static IApplicationBuilder UseCustomException(this IApplicationBuilder app, CustomExceptionMiddleWareOption option)
         {
         return app.UseMiddleware<CustomExceptionMiddleWare>(option);
         }
         }

        在Startup.cs的Configuref方法中注冊異常中間件

         app.UseCustomException(new CustomExceptionMiddleWareOption(
         handleType: CustomExceptionHandleType.Both, //根據(jù)url關(guān)鍵字決定處理方式
         jsonHandleUrlKeys: new PathString[] { "/api" },
         errorHandingPath: "/home/error"));

        接下來我們來進(jìn)行測試,首先模擬一個(gè)將會進(jìn)行頁面跳轉(zhuǎn)的未經(jīng)捕獲的異常

        訪問/home/about的結(jié)果

        訪問/home/test的結(jié)果 (該地址不存在)

        OK異常跳轉(zhuǎn)頁面的方式測試完成,接下來我們測試返回統(tǒng)一格式(json)的異常處理,同樣先模擬一個(gè)未經(jīng)捕獲的異常

        訪問/api/token/gettesterror的結(jié)果

        訪問/api/token/test的結(jié)果 (該地址不存在)

        訪問/api/token/getvalue的結(jié)果 (該接口需要身份驗(yàn)證)

        測試完成,頁面跳轉(zhuǎn)和統(tǒng)一格式返回都沒有問題,自定義異常中間件已按預(yù)期工作

        需要注意的是,自定義中間件會響應(yīng)每個(gè)HTTP請求,所以處理邏輯一定要精簡,防止發(fā)生不必要的性能問題

        總結(jié)

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        ASP.NET CORE學(xué)習(xí)教程之自定義異常處理詳解

        ASP.NET CORE學(xué)習(xí)教程之自定義異常處理詳解:為什么異常處理選擇中間件? 傳統(tǒng)的ASP.NET可以采用異常過濾器的方式處理異常,在ASP.NET CORE中,是以多個(gè)中間件連接而成的管道形式處理請求的,不過常用的五大過濾器得以保留,同樣可以采用異常過濾器處理異常,但是異常過濾器不能處理MVC中間件以外的異
        推薦度:
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 国产成人精品免费午夜app| a级在线观看免费| 最近的中文字幕大全免费版| 久久久久亚洲精品无码蜜桃| 最新免费jlzzjlzz在线播放| 亚洲精品中文字幕无乱码| 久久久精品午夜免费不卡| 亚洲AV日韩AV永久无码免下载| 成人毛片100免费观看| 亚洲色精品vr一区二区三区| 国产精品高清视亚洲一区二区| 99久久99这里只有免费费精品 | 亚洲Aⅴ在线无码播放毛片一线天| 毛片在线看免费版| 亚洲人成色77777在线观看| 精品久久洲久久久久护士免费 | caoporn成人免费公开| 亚洲宅男天堂在线观看无病毒| 中文字幕无线码免费人妻| 久久精品国产精品亚洲艾草网 | 日本免费一区二区久久人人澡| 亚洲好看的理论片电影| 亚洲三级高清免费| 色屁屁www影院免费观看视频| 亚洲日韩涩涩成人午夜私人影院| 在线观看人成视频免费无遮挡| 亚洲国产成人高清在线观看| 69堂人成无码免费视频果冻传媒 | 亚洲精品福利你懂| 免费在线不卡视频| 久久久国产精品无码免费专区| 亚洲免费在线观看视频| 亚洲Aⅴ无码一区二区二三区软件| 鲁丝片一区二区三区免费| 亚洲中文字幕人成乱码| 俄罗斯极品美女毛片免费播放| 永久免费av无码入口国语片| 亚洲一本一道一区二区三区| 亚洲色欲久久久综合网| 97无码免费人妻超级碰碰碰碰| 一级毛片免费观看不收费|