.NetCore 请求WebAPI响应信息记录到数据库


环境:.NetCore3.1、VS2019、Web API模板、SqlSugar、MSSqlServer

思路:我们要把每次HTTP请求响应的信息都保存到数据库,因为每次HTTP都会走一遍中间件,我们可以把写入数据库的操作写在自定义中间件上。但是它做的事情比较多,后续也可能变更需求,所有我决定把这个事情写在自定义服务上,让中间件使用该服务进行写入数据库操作。

1.新建服务对应的接口。

public interface IApiLogService
    {
        void DataSave(HttpContext context, long responseTime);
    }

 

2.新建服务。

2.1.需要安装Nuget包sqlSugarCore,当然也可以使用其他ORM,本例只支持单例模式连接数据库的ORM。

 

2.2.添加数据库连接。需要在此数据库连接字符串上的服务器地址新建数据库,本人使用本地的SqlServer。

1 services.AddSingleton(new SqlSugarClient(new ConnectionConfig
2             {
3                 ConnectionString = "server=.;uid=sa;pwd=sasa;database=apilogdemo;MultipleActiveResultSets=true",//必填, 数据库连接字符串
4                 DbType = DbType.SqlServer,         //必填, 数据库类型
5                 IsAutoCloseConnection = true,       //默认false, 时候知道关闭数据库连接, 设置为true无需使用using或者Close操作
6                 InitKeyType = InitKeyType.SystemTable    //默认SystemTable, 字段信息读取, 如:该属性是不是主键,是不是标识列等等信息
7             }));

 1 public class ApiLogService : IApiLogService
 2     {
 3         private readonly IConfiguration _configuration;
 4         private readonly SqlSugarClient _dbContext;
 5 
 6         public ApiLogService(IConfiguration configuration, SqlSugarClient dbContext)
 7         {
 8             _configuration = configuration;
 9             _dbContext = dbContext;
10         }
11 
12         public void DataSave(HttpContext context, long responseTime)
13         {
14             var isLog = _configuration.GetValue<bool>("ApiLog:IsEnable");
15             if (isLog)
16             {
17                 var requestMethod = context.Request.Method;
18                 var requestURL = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}";
19                 //var accessToken = context.GetTokenAsync("access_token").Result;//添加身份验证的项目可以使用此方法获取到access_toekn
20                 var accessToken = string.Empty;
21                 var requestBody = string.Empty;
22                 if (requestMethod == "POST")
23                 {
24                     context.Request.Body.Seek(0, SeekOrigin.Begin);
25                     var _reader = new StreamReader(context.Request.Body);
26                     requestBody = _reader.ReadToEnd();
27                 }
28                 _dbContext.Insertable(new ApiLog
29                 {
30                     AccessToken = accessToken,
31                     AccessTime = DateTime.Now,
32                     AccessAction = requestMethod,
33                     AccessApiUrl = requestURL,
34                     QueryString = context.Request.QueryString.ToString(),
35                     Body = requestBody,
36                     HttpStatus = context.Response.StatusCode,
37                     ClientIP = context.Connection.RemoteIpAddress.ToString(),
38                     ResponseTime = responseTime
39                 }).ExecuteCommand();
40             }
41         }
42     }

 

2.3.需要在appsettion.json/appsetting.Development.json文件添加配置信息,用于控制是否启用响应日志,当然也可以不控制。

"ApiLog": {
    "IsEnable": true
  }

 

2.4.添加响应日志实体,需要在数据库上添加该表。

 1     /// <summary>
 2     /// 接口请求日志
 3     /// </summary>
 4     public class ApiLog
 5     {
 6         /// <summary>
 7         /// Desc:
 8         /// Default:
 9         /// Nullable:False
10         /// </summary>           
11         public int ALgID { get; set; }
12 
13         /// <summary>
14         /// Desc:
15         /// Default:
16         /// Nullable:True
17         /// </summary>           
18         public string ClientIP { get; set; }
19 
20         /// <summary>
21         /// Desc:
22         /// Default:
23         /// Nullable:False
24         /// </summary>           
25         public long ResponseTime { get; set; }
26 
27         /// <summary>
28         /// Desc:
29         /// Default:
30         /// Nullable:True
31         /// </summary>           
32         public string AccessToken { get; set; }
33 
34         /// <summary>
35         /// Desc:
36         /// Default:
37         /// Nullable:False
38         /// </summary>           
39         public DateTime AccessTime { get; set; }
40 
41         /// <summary>
42         /// Desc:
43         /// Default:
44         /// Nullable:True
45         /// </summary>           
46         public string AccessApiUrl { get; set; }
47 
48         /// <summary>
49         /// Desc:
50         /// Default:
51         /// Nullable:True
52         /// </summary>           
53         public string AccessAction { get; set; }
54 
55         /// <summary>
56         /// Desc:
57         /// Default:
58         /// Nullable:True
59         /// </summary>           
60         public string QueryString { get; set; }
61 
62         /// <summary>
63         /// Desc:
64         /// Default:
65         /// Nullable:True
66         /// </summary>           
67         public string Body { get; set; }
68 
69         /// <summary>
70         /// Desc:
71         /// Default:
72         /// Nullable:False
73         /// </summary>           
74         public int HttpStatus { get; set; }
75     }

 

3.此时,我们的服务已经定义好了。接下来是自定义一个中间件。

3.1.新建中间件,注入并使用刚才定义好的服务。

 1 public class LogMiddleware
 2     {
 3         private readonly RequestDelegate _next;
 4         private readonly IApiLogService _apiLogService;
 5         private readonly IConfiguration _configration;
 6 
 7         public LogMiddleware(RequestDelegate next, IApiLogService apiLogService, IConfiguration configration)
 8         {
 9             _next = next;
10             _apiLogService = apiLogService;
11             _configration = configration;
12         }
13 
14         public Task Invoke(HttpContext context)
15         {
16             var watch = new Stopwatch();
17             watch.Start();
18             context.Response.OnStarting(() =>
19             {
20                 var isLog = _configration.GetValue<bool>("ApiLog:IsEnable");
21                 if (isLog)
22                 {
23                     watch.Stop();
24                     _apiLogService.DataSave(context, watch.ElapsedMilliseconds);
25                 }
26                 return Task.CompletedTask;
27             });
28             
29             return this._next(context);
30         }
31     }

 

 3.2.新建暴露中间件扩展类。

1 public static class LogMiddlewareExtension
2     {
3         public static IApplicationBuilder UseLogMiddleware(this IApplicationBuilder builder)
4         {
5             return builder.UseMiddleware<LogMiddleware>();
6         }
7     }

 

4.我们的工作已经做好了,接下来使用自定义的中间件就可以了。

4.1.添加自定义服务

services.AddSingleton<IApiLogService, ApiLogService>();

 

 4.2.使用自定义中间件。

app.UseLogMiddleware();

 

 5.运行项目,查看效果。

 源码地址:https://github.com/Jcanc/WebApiResponseLog


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM