using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using WIDESEA_Core.Helper; using WIDESEA_Core.LogHelper; namespace WIDESEA_Core.Middlewares { /// /// 记录请求和响应数据 /// public class ApiLogMiddleware { /// /// /// private readonly RequestDelegate _next; public ApiLogMiddleware(RequestDelegate next) { _next = next; } //todo public async Task InvokeAsync(HttpContext context) { if (App.ExpDateTime != null && (DateTime.Now - App.ExpDateTime.GetValueOrDefault()).TotalSeconds > 0) { context.Response.StatusCode = HttpStatusCode.InternalServerError.ObjToInt(); context.Response.ContentType = "application/json"; var json = new WebResponseContent(); json.Message = HttpStatusCode.InternalServerError.ToString();//错误信息 json.Code = 500;//500异常 StreamWriter streamWriter = new StreamWriter(context.Response.Body); await streamWriter.WriteAsync(json.Serialize()); return; } // 过滤,只有接口 if (context.Request.Path.Value?.Contains("api") ?? false) { context.Request.EnableBuffering(); Stream originalBody = context.Response.Body; string requestParam = string.Empty; string responseParam = string.Empty; try { (context.RequestServices.GetService(typeof(RequestLogModel)) as RequestLogModel).RequestDate = DateTime.Now; try { // 存储请求数据 requestParam = RequestDataLog(context); context.Request.Body.Position = 0; } catch { } using MemoryStream ms = new(); context.Response.Body = ms; await _next(context); try { // 存储响应数据 responseParam = ResponseDataLog(context.Response); } catch { } ms.Position = 0; await ms.CopyToAsync(originalBody); if (!((context.Request.Path.Value?.Contains("get")) ?? true) && !((context.Request.Path.Value?.Contains("Get")) ?? true) && !((context.Request.Path.Value?.Contains("query")) ?? true) && !((context.Request.Path.Value?.Contains("Query")) ?? true) && !((context.Request.Path.Value?.Contains("DownLoadApp")) ?? true) && !((context.Request.Path.Value?.Contains("downLoadApp")) ?? true) && !((context.Request.Path.Value?.Contains("UploadApp")) ?? true) && !((context.Request.Path.Value?.Contains("uploadApp")) ?? true)) Logger.Add(requestParam, responseParam); } catch (Exception ex) { // 记录异常 } finally { context.Response.Body = originalBody; } } else { await _next(context); } } private string RequestDataLog(HttpContext context) { var request = context.Request; var sr = new StreamReader(request.Body); object obj; string bodyData = sr.ReadToEndAsync().Result; if (request.ContentLength <= 100000) { obj = new { QueryString = request.QueryString.ToString(), BodyData = bodyData }; } else { obj = new { QueryString = request.QueryString.ToString(), BodyData = "" }; } string data = JsonConvert.SerializeObject(obj); request.Body.Position = 0; return data; } private string ResponseDataLog(HttpResponse response) { if (response.ContentLength <= 100000) { response.Body.Position = 0; using StreamReader stream = new StreamReader(response.Body, leaveOpen: true); string body = stream.ReadToEnd(); response.Body.Position = 0; return body; } return ""; } //private async Task RequestDataLog(HttpContext context) //{ // var request = context.Request; // var sr = new StreamReader(request.Body); // //long length = request.Body.Length; // RequestLogInfo requestResponse = new RequestLogInfo() // { // Path = request.Path, // QueryString = request.QueryString.ToString(), // BodyData = await sr.ReadToEndAsync() // }; // var content = JsonConvert.SerializeObject(requestResponse); // if (!string.IsNullOrEmpty(content)) // { // LogLock.OutLogAOP("接口日志", new string[] { "请求数据 - 请求数据类型:" + requestResponse.GetType().ToString(), content }); // request.Body.Position = 0; // } //} private void ResponseDataLog(HttpResponse response, MemoryStream ms) { ms.Position = 0; var responseBody = new StreamReader(ms).ReadToEnd(); // 去除 Html var reg = "<[^>]+>"; var isHtml = Regex.IsMatch(responseBody, reg); if (!string.IsNullOrEmpty(responseBody)) { Parallel.For(0, 1, e => { LogLock.OutLogAOP("接口日志", new string[] { "响应数据 - 响应数据类型:" + responseBody.GetType().ToString(), responseBody }); }); } } } public class RequestLogInfo { /// /// 请求地址 /// public string Path { get; set; } /// /// 请求参数 /// public string QueryString { get; set; } /// /// Body参数 /// public string BodyData { get; set; } } }