首页 > 编程语言 >【C#进阶】.NET Core 中的筛选器 Filter【ActionFilterAttribute 操作筛选器,实现日志记录】

【C#进阶】.NET Core 中的筛选器 Filter【ActionFilterAttribute 操作筛选器,实现日志记录】

时间:2023-02-23 11:56:22浏览次数:57  
标签:Core 进阶 请求 request context using 筛选 public string

 

筛选器 Filter介绍 :【C#进阶】.NET Core 中的筛选器 Filter - C#初级程序员 - 博客园 (cnblogs.com)

 

ActionFilterAttribute 操作筛选器,实现日志记录

第一步 创建.NET CORE项目
第二步 创建操作筛选器重写类BasicAuthAttribute ,继承ActionFilterAttribute

其中 AddRequestLog、EditRequestLog这两个方法为记录请求日志,本文为记录到数据库,可以自行修改

  1 using Demo.Infrastructure;
  2 using Microsoft.AspNetCore.Http;
  3 using Microsoft.AspNetCore.Mvc;
  4 using Microsoft.AspNetCore.Mvc.Controllers;
  5 using Microsoft.AspNetCore.Mvc.Filters;
  6 using System;
  7 using System.Collections.Generic;
  8 using System.Linq;
  9 using System.Text;
 10 using System.Threading.Tasks;
 11 
 12 namespace Demo
 13 {
 14     /// <summary>
 15     /// 重写请求拦截器
 16     /// </summary>
 17     public class BasicAuthAttribute : ActionFilterAttribute
 18     {
 19         /// <summary>
 20         /// Action方法调用之前执行 
 21         /// </summary>
 22         /// <param name="context "></param>
 23         public override void OnActionExecuting(ActionExecutingContext context)
 24         {
 25             try
 26             {
 27                 HttpRequest request = context.HttpContext.Request;
 28                 ////获取请求头中的Token和TimeSpan
 29                 //var token = context.HttpContext.Request.Headers["Token"].ToString();
 30                 //var timespan = context.HttpContext.Request.Headers["TimeSpan"].ToString();
 31 
 32                 //string token = request.Headers["token"];
 33 
 34                 var descriptor = context.ActionDescriptor as ControllerActionDescriptor;
 35                 //记录进入请求的时间
 36                 descriptor.Properties["enterTime"] = DateTime.Now.ToBinary();
 37                 string Id = Guid.NewGuid().ToString().Substring(0, 12);
 38                 //记录日志Id
 39                 descriptor.Properties["Id"] = Id;
 40 
 41                 //获取action名称
 42                 string actionName = descriptor.ActionName;
 43                 //获取Controller 名称
 44                 string controllerName = descriptor.ControllerName;
 45                 //获取action开始执行的时间
 46                 DateTime enterTime = DateTime.Now;
 47                 //获取访问的ip 及 端口
 48                 string ip = context.HttpContext.Connection.RemoteIpAddress.ToString() + ':' + context.HttpContext.Connection.RemotePort.ToString();
 49                 //获取用户主机名
 50                 string userHostName = request.Host.Value;
 51 
 52                 //获取完整请求地址
 53                 string urlReferrer = new StringBuilder()
 54                 .Append(request.Scheme)
 55                 .Append("://")
 56                 .Append(request.Host)
 57                 .Append(request.PathBase)
 58                 .Append(request.Path)
 59                 .Append(request.QueryString)
 60                 .ToString();
 61                 //获取请求的浏览器名称
 62                 string browser = request.Headers["User-Agent"];
 63                 //string userHostName = request.UserHostName;
 64                 //string urlReferrer = request.UrlReferrer != null ? request.UrlReferrer.AbsoluteUri : "";
 65                 //string browser = request.Browser.Browser + " - " + request.Browser.Version + " - " + request.Browser.Type;
 66 
 67                 //获取request提交的参数
 68                 string param = string.Empty;
 69                 string globalParam = string.Empty;
 70                 foreach (var arg in context.ActionArguments)
 71                 {
 72                     string value = Newtonsoft.Json.JsonConvert.SerializeObject(arg.Value);
 73                     param += $"{arg.Key} : {value} \r\n";
 74                     globalParam += value;
 75                 }
 76                 //写入日志记录
 77                 AddRequestLog(Id, Newtonsoft.Json.JsonConvert.SerializeObject(request.Headers), actionName, controllerName, urlReferrer, param, enterTime, ip, userHostName, browser);
 78             }
 79             catch (Exception ex) { }
 80         }
 81 
 82         /// <summary>
 83         /// Action 方法调用后。Result 方法调用前执行
 84         /// </summary>
 85         /// <param name="context"></param>
 86         public override void OnActionExecuted(ActionExecutedContext context) { }
 87 
 88         /// <summary>
 89         /// Result 方法调用前执行
 90         /// </summary>
 91         /// <param name="context"></param>
 92         public override void OnResultExecuting(ResultExecutingContext context) { }
 93 
 94         /// <summary>
 95         /// Result 方法调用后执行
 96         /// </summary>
 97         /// <param name="context"></param>
 98         public override void OnResultExecuted(ResultExecutedContext context)
 99         {
100             try
101             {
102                 HttpResponse response = context.HttpContext.Response;
103 
104                 var descriptor = context.ActionDescriptor as ControllerActionDescriptor;
105                 object beginTime = null;
106                 double costTime = 0;
107                 DateTime nowDate = DateTime.Now;
108                 object id = "";
109                 if (descriptor.Properties.TryGetValue("enterTime", out beginTime))
110                 {
111                     //获取进入请求的时间
112                     DateTime time = DateTime.FromBinary(Convert.ToInt64(beginTime));
113                     //获取执行action的耗时
114                     costTime = (nowDate - time).TotalMilliseconds;
115                 }
116                 if (descriptor.Properties.TryGetValue("Id", out id)) { }
117                 //获取response响应的结果
118                 string result = string.Empty;
119                 if (context.Result is ObjectResult)
120                     result = Newtonsoft.Json.JsonConvert.SerializeObject(((ObjectResult)context.Result).Value);
121                 if (!string.IsNullOrEmpty(id.ToString()) && id.ToString() != "")
122                 {
123                     EditRequestLog(id.ToString(), Newtonsoft.Json.JsonConvert.SerializeObject(response.Headers), result, nowDate, costTime);
124                 }
125             }
126             catch (Exception ex) { }
127         }
128 
129 
130         /// <summary>
131         /// 添加Api请求记录
132         /// </summary>
133         /// <param name="ApiRequestLogId">请求日志Id</param>
134         /// <param name="Headers">请求头部信息</param>
135         /// <param name="ActionName">请求方法名</param>
136         /// <param name="ControllerName">请求控制器名</param>
137         /// <param name="UrlReferrer">请求完整地址</param>
138         /// <param name="RequestParam">请求参数</param>
139         /// <param name="TimeOn">请求开始时间</param>
140         /// <param name="IpAddress">请求Ip地址</param>
141         /// <param name="HostName">请求主机名</param>
142         /// <param name="Browser">请求浏览器信息</param>
143         public void AddRequestLog(string ApiRequestLogId, string Headers, string ActionName, string ControllerName, string UrlReferrer, string RequestParam, DateTime TimeOn, string IpAddress, string HostName, string Browser)
144         {
145             // sapParameter = sapParameter.Replace("'","\"");
146             string sqlstr = $@"INSERT INTO dbo.ApiRequestLog
147                     (
148                         ApiRequestLogId,
149                         Headers,
150                         ActionName,
151                         ControllerName,
152                         UrlReferrer,
153                         RequestParam,
154                         TimeOn,
155                         IpAddress,
156                         HostName,
157                         Browser
158                     )
159                     VALUES
160                     (   '{ApiRequestLogId}', -- ApiRequestLogId - char(12)
161                         '{Headers}',    -- Headers - nvarchar(500)
162                         '{ActionName}',    -- ActionName - nvarchar(50)
163                         '{ControllerName}',    -- ControllerName - nvarchar(50)
164                         '{UrlReferrer}',    -- UrlReferrer - nvarchar(500)
165                         '{RequestParam}',    -- RequestParam - nvarchar(max)
166                         '{TimeOn}',    -- TimeOn - datetime
167                         '{IpAddress}',    -- IpAddress - nvarchar(50)
168                         '{HostName}',    -- HostName - nvarchar(50)
169                         '{Browser}'    -- Browser - nvarchar(500)
170                         )";
171 
172             // _logger.LogError(sqlstr);
173             try
174             {
175                 var count = DapperHelper<int>.Execute(sqlstr, null);
176             }
177             catch (Exception ex) { }
178         }
179 
180         /// <summary>
181         /// 更新Api请求记录
182         /// </summary>
183         /// <param name="ApiRequestLogId">接口日志Id</param>
184         /// <param name="Response">响应头</param>
185         /// <param name="ResultParam">返回参数</param>
186         /// <param name="TimeOff">请求结束时间</param>
187         /// <param name="CostTime">请求耗时(ms)</param>
188         public void EditRequestLog(string ApiRequestLogId, string Response, string ResultParam, DateTime TimeOff, double CostTime)
189         {
190             string sqlstr = $@"UPDATE dbo.ApiRequestLog SET Response = '{Response}',ResultParam = '{ResultParam}',TimeOff = '{TimeOff}',CostTime = '{CostTime}' WHERE ApiRequestLogId = '{ApiRequestLogId}'";
191             try
192             {
193                 var count = DapperHelper<int>.Execute(sqlstr, null);
194             }
195             catch (Exception ex) { }
196         }
197     }
198     /// <summary>
199     /// 不需要登陆的地方加个这个空的拦载器
200     /// </summary>
201     public class NoSignAttribute : ActionFilterAttribute { }
202 
203 }

第三步:依赖注入 在Startup.cs中进行依赖注入

 1 public void ConfigureServices(IServiceCollection services)
 2         {
 3 
 4             #region 全局注册自定义特性
 5             services.AddControllers(options =>
 6             {
 7                 //全局注册请求拦截器
 8                 options.Filters.Add(typeof(BasicAuthAttribute));
 9             });
10             #endregion
11         }

 

第四步:新建控制器测试

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Net.Http;
  5 using System.Threading.Tasks; 12 using Microsoft.AspNetCore.Http;
 13 using Microsoft.AspNetCore.Mvc;
 14 using Microsoft.Extensions.Configuration;

19 namespace API.JMGO.COM.Controllers 20 { 21 [Route("api/[controller]/[action]")] 22 [ApiController] 23 public class ActivationDataController : ControllerBase 24 {163 /// <summary> 164 /// 测试 165 /// </summary> 166 /// <returns></returns> 167 [HttpGet("TestGet")] 168 public IActionResult TestGet() 169 { 170 var cfRt = appSettingsJson["apiurl"];//读取配置文件 171 return Ok(cfRt); 172 }188 } 189 }

第五步:查看数据库日志是否记录

 

标签:Core,进阶,请求,request,context,using,筛选,public,string
From: https://www.cnblogs.com/2023-02-14/p/16868884.html

相关文章

  • docker 本地linux环境调试 .net 代码 —— debugging dockerized .NET core applicat
    原文:HowtoDebugDockerized.NETCoreAppsinVSCode(freecodecamp.org) vscoderundockercommand:dockerimagebuild--pull--file"C:\[path]/[projectN......
  • Net Core 3.1 ONVIF 操控海康摄像头
    先给出实现的代码https://github.com/lu1770/onvif-client.git这里实现了设备发现,登录,获得码流列表,获得画面rtsp,vlc播放,云台上下左右控制,放大缩小安装nuget包......
  • 【JS】JavaScript进阶 ES6 - 黑马视频笔记
    1.作用域作用域(scope)规定了变量能够被访问的“范围”,离开这个范围变量便不能被访问。分为:局部作用域、全局作用域。1.1局部作用域局部作用域分为:函数作用域、块作用......
  • SQL进阶-存储引擎
    1.MySQL体系结构连接层最上层是一些客户端和链接服务,主要完成一些类似于连接处理、授权认证、及相关的安全方案。服务器也会为安全接入的每个客户端验证它所具有的......
  • Javascript进阶
    Javascript进阶一.变量提升看以下代码,或多或少会有些问题的.functionfn(){console.log(name);varname='大马猴';}fn()发现问题了么.这么写代码,......
  • .NetCore自定义模板,发布Nuget
    1.创建模板项目框架             2.创建模板文件在项目文件夹根目录创建.template.config文件夹,在文件夹下创建新的文件:template.json  ......
  • .net core abp框架ddd分层如何做ef core迁移和恢复迁移
    一、从模型迁移到数据库1、visualstudio启动项里选择对应的项目,修改appsettings.json里的数据库链接(决定迁移到那个服务器以及数据库)2、打开Nuget管理控制台,执行Add-Mi......
  • 推荐一款.Net Core开发的后台管理系统YiShaAdmin
    若依(RuoYi)是码云上一款精美的开源快速开发平台,作者毫无保留给个人及企业免费使用。RuoYi目前有三个版本:普通版本(RuoYi)、前后端分离版本(RuoYi-Vue)、微服务版本(RuoYi-Cl......
  • 5 .NET Core笔试题
    1.说说你知道的ORM框架?2.请问对EFCore有了解吗?3.说说EFCore查询的性能调优小技巧?4.EFCore如果通过数据生成实体和DbContext?5.说说对SaveChanges的理解?6.说说对EFCo......
  • aspnetcore 原生 DI 实现基于 key 的服务获取
    你可能想通过一个字符串或者其他的类型来获取一个具体的服务实现,那么在aspnetcore原生的MSDI中,如何实现呢?本文将介绍如何通过自定义工厂来实现。我们现在恰好有基于J......