<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      1.繼承IExceptionFilter只是用于記錄全局異常異常日志,現(xiàn)在我想記錄每個請求的日志并且入庫。

      需要用到IAsyncActionFilter,繼承該接口,用于記錄每一個action方法的請求信息,作用是記錄每個操作的記錄,簡單點來講就是記錄哪個人調(diào)用了哪個方法。

      添加一個繼承該接口的過濾器,并添加所需操作,這里就是記錄每一個請求的操作記錄

          public class LogActionFilter(ILoggingService loggingService) : IAsyncActionFilter
          {
              private readonly ILoggingService _loggingService = loggingService;
      
              /// <summary>
              /// 日志記錄-Action層級
              /// </summary>
              public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
              {
                  var result = await next();
                  var log = new LogModel
                  {
                      Content = result.Exception == null ? "操作記錄" : result.Exception.Message,
                      CreateTime = DateTime.Now,
                      Level = result.Exception == null ? 0 : 1,
                      Controller = result.HttpContext.Request.RouteValues["controller"] as string ?? "",
                      Action = result.HttpContext.Request.RouteValues["action"] as string ?? "",
                      Source = result.HttpContext.Request.Path,
                      Name = "測試用戶"
                  };
                  await _loggingService.InsertAsync(log);
              }
          }

      注入該過濾器到全局。這里我是為了簡潔program,把注入的操作添加到靜態(tài)類,也可以在program里面build.services…注入到全局控制器…

              /// <summary>
              /// 注冊記錄日志過濾器
              /// </summary>
              public static void AddActionFilterModule(this IServiceCollection services)
              {
                  services.AddControllers(option =>
                  {
                      option.Filters.Add(typeof(LogActionFilter));
                  });
              }

      本身并沒有太多操作,但是沒用過難免就不知道,比如我…以前都是哪里記錄日志就單獨寫一下,沒有使用過全局的。


       

      分割線上面的可以記錄到正常的操作記錄,后面我添加了jwt登錄驗證,就引發(fā)了另外的問題。

      假如token錯誤,或者未輸入,我做了處理,讓錯誤異常返回統(tǒng)一的格式,而不是單純的把異常拋出到前端。但是因為此時還沒有進入控制器,屬于是中間件級別的異常,上面的IExceptionFilter和IAsyncActionFilter過濾器只是過濾action級別的。因此異常和日志無法記錄。

      解決方式是通過中間件!

      不知道大家是不是經(jīng)常使用中間件,不算難,但是不經(jīng)常用,就總會忘。

      中間件的添加是app.UseMiddleware<>()

      也可以直接

      app.Use(async (context, next)=>{}); 

       

       中間件的執(zhí)行順序是執(zhí)行完第一個再執(zhí)行第二個。依次執(zhí)行

      添加一個類,RequestDelegate 是必要的一個委托條件,作用就是執(zhí)行下一個中間件。ILoggingService是我記錄日志入庫的接口,注入進來

       要添加一個Invoke方法。參數(shù)為:HttpContext。 這個參數(shù)就是HTTP請求的一些信息。

      通過代碼可知:_next(context)  就是把http請求內(nèi)容放到委托,用于執(zhí)行下一個中間件操作。

      因為中間件異常通過過濾器獲取不到,這里就通過trycatch來在中間件里攔截,進行處理。

              public class LogAopFilter(ILoggingService loggingService, RequestDelegate next)
              {
                  private readonly RequestDelegate _next = next;
                  private readonly ILoggingService _loggingService = loggingService;
      
                  public async Task Invoke(HttpContext context)
                  {
                      try
                      {
                          await _next(context);
                      }
                      catch (HttpException ex)
                      {
                          #region 過濾中間件異常并自定義返回結(jié)果
      
                          context.Response.StatusCode = ex.StatusCode;
                          context.Response.ContentType = "application/json";
                          var errorResponse = new R
                          {
                              Code = StateCode.ERROR,
                              Data = null,
                              Msg = ex.Message
                          };
                          var jsonErrorResponse = JsonConvert.SerializeObject(errorResponse);
                          await context.Response.WriteAsync(jsonErrorResponse);
      
                          #endregion 過濾中間件異常并自定義返回結(jié)果
      
                          #region 異常日志記錄
      
                          var log = new LogModel
                          {
                              Content = ex.Message,
                              CreateTime = DateTime.Now,
                              Level = 1,
                              Source = ex.Source ?? "",
                              Name = "測試用戶"
                          };
                          await _loggingService.InsertAsync(log);
      
                          #endregion 異常日志記錄
                      }
                  }
              }

       

       最后就是注入中間件即可。還是為了簡潔program。做一個靜態(tài)類注入直接調(diào)用即可

              /// <summary>
              /// 統(tǒng)一添加中間件
              /// 1.捕捉中間件級別異常
              /// </summary>
              /// <param name="builder"></param>
              public static void UseAopModule(this IApplicationBuilder builder)
              {
                  builder.UseMiddleware<LogAopFilter>();           
              }

       

       以下是另一種寫法:在program里面直接使用app.use ,一開始是在program里面寫的,嫌棄太長了,搞得program看著不好看,就沒這么寫,看個人喜歡吧

                  app.Use(async (context, next) =>
                  {
                      try
                      {
                          await next.Invoke(context);
                      }
                      catch (HttpException ex)
                      {
                          #region 過濾中間件異常
      
                          context.Response.StatusCode = ex.StatusCode;
                          context.Response.ContentType = "application/json";
                          var errorResponse = new R
                          {
                              Code = StateCode.ERROR,
                              Data = null,
                              Msg = ex.Message
                          };
                          var jsonErrorResponse = JsonConvert.SerializeObject(errorResponse);
                          await context.Response.WriteAsync(jsonErrorResponse);
      
                          #endregion 過濾中間件異常
                      }
                  });

       

       下面就是效果截圖。不輸入token讓他報錯,一般不處理他就是401。因為我想更人性化,會分辨出是token沒有或者是token錯誤,或者是token過期,我認證的部分有處理,丟出相應的錯誤信息,為的就是方便好處理,故此我的這個接口正常情況下是401+錯誤信息。

      錯誤信息我經(jīng)過中間件的處理,和正常接口返回的結(jié)構(gòu)是一樣的,這樣方便前端去處理,只記住一種返回結(jié)構(gòu)就行了

       日志內(nèi)容截圖

       

      大致就是如此啦


       

      追加一部分,原本token認證那邊我是手動拋異常來讓程序的全局異常來捕捉。調(diào)試的時候總是會中斷程序,雖然實際發(fā)布了并不會影響什么,但是目前太影響了。所以稍微改了一下,大體上沒什么變化。代碼如下 。

      這是token認證里面的代碼,OnChallenge 就是token異常的時候會執(zhí)行,在此修改狀態(tài)碼,和返回內(nèi)容即可。不懂這塊兒可以搜一下jwt相關內(nèi)容,或者用不到可以不看

      這里的處理是用于返回自定義內(nèi)容。

      //當JWT Bearer認證失敗時,即請求未包含有效的JWT令牌或令牌驗證失敗,該事件會被觸發(fā)
      OnChallenge = context =>
      {
          context.HandleResponse();
          context.Response.StatusCode = 401;
          context.Response.ContentType = "application/json";
          var errMsg = $"Token無效: {(string.IsNullOrEmpty(context.ErrorDescription) ? "請輸入正確的Token" : context.ErrorDescription)}";
          var errSource = "Token認證失敗";
          var errorResponse = new R
          {
              Code = StateCode.ERROR,
              Data = null,
              Msg = errMsg
          };
          context.HttpContext.Items.Add("errror", errMsg);
          context.HttpContext.Items.Add("source", errSource);
      
          var jsonErrorResponse = JsonConvert.SerializeObject(errorResponse);
          return context.Response.WriteAsync(jsonErrorResponse);
      }

      前文說過了, Token認證這一部分的異常算是中間件級別,不會觸發(fā)全局異常過濾器。只能在中間件處理(也許有別的方法),但取消掉了手動異常,日志可能就無法完整記錄,因此…看代碼!

      其實就是加上finally,最后判斷下是不是200狀態(tài)碼,如果不是就記錄日志,200的狀態(tài)碼那就是成功的請求,自有異常過濾器處理,這里主要針對中間件級別的異常處理的。

                      try
                      {
                          await _next(context);
                      }
                      catch (HttpException ex)
                      {
                      }
                      finally
                      {
                          if (context.Response.StatusCode != 200)
                          {
                              #region 異常日志記錄
                              var log = new LogModel
                              {
                                  Content = context.Items["errror"] as string ?? "操作失敗",
                                  CreateTime = DateTime.Now,
                                  Level = 1,
                                  Source = context.Items["source"] as string ?? "中間件異常",
                                  Name = "測試用戶"
                              };
                              await _loggingService.InsertAsync(log);
                              #endregion 異常日志記錄
                          }
                      }

       

      真的拜拜了

      posted on 2024-01-03 13:56  嘗嘗手指  閱讀(868)  評論(1)    收藏  舉報

      主站蜘蛛池模板: 国产精品亚洲二区在线看| 国产一区二区四区不卡| 国产一区二区三区的视频 | 久久综合亚洲色一区二区三区| 日日爽日日操| 免费无码又爽又刺激网站直播| 欧美三级欧美成人高清| 欧美大胆老熟妇乱子伦视频| 亚洲精品无码乱码成人| 国产黄色一区二区三区四区| 亚洲一区二区日韩综合久久| 亚洲日本高清一区二区三区| 宁城县| 国产69精品久久久久人妻刘玥| 无套内谢极品少妇视频| 99久久精品久久久久久婷婷| 四虎国产精品永久入口| 色偷偷成人综合亚洲精品| 亚洲av第一区二区三区| 久久精品熟妇丰满人妻久久| 国产桃色在线成免费视频| XXXXXHD亚洲日本HD| 欧美日韩国产亚洲沙发| 国产区精品视频自产自拍| 国产精品一区二区三区四区| 国产成人高清亚洲综合| 久草热大美女黄色片免费看| 日韩中文字幕精品人妻| 亚洲乱人伦中文字幕无码| 在线看片免费人成视久网| 丝袜高潮流白浆潮喷在线播放| 精品国产欧美一区二区三区在线| 欧美成人h亚洲综合在线观看| 岛国一区二区三区高清视频| 日本熟妇XXXX潮喷视频| av在线网站手机播放| 激烈的性高湖波多野结衣| 中文字幕亚洲综合第一页| 蜜臀av一区二区三区日韩| 精品无码国产日韩制服丝袜| 国产一区二区av天堂热|