.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