核心问题: .net Core自定义中间件中读取Request.Body和Response.Body的内容
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// 扩展中间件
/// </summary>
public static class ErrorHandlingMiddlewareExtensions
{
public static IApplicationBuilder UseRequestResponseLogging(this IApplicationBuilder app)
{
return app.UseMiddleware<ErrorHandlingMiddleware>();
}
}
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate _next;
private SortedDictionary<string, object> _data;
private Stopwatch _stopwatch;
public ErrorHandlingMiddleware(RequestDelegate next)
{
_next = next;
_stopwatch = new Stopwatch();
}
public async Task Invoke(HttpContext context)
{
_stopwatch.Restart();
_data = new SortedDictionary<string, object>();
//启用读取request
context.Request.EnableBuffering();
var request = context.Request;
var response = context.Response;
#region 存档request
_data.Add("request.url", request.Path.ToString());
_data.Add("request.headers", request.Headers.ToDictionary(x => x.Key, v => string.Join(";", v.Value.ToList())));
_data.Add("request.method", request.Method);
_data.Add("request.executeStartTime", DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
if (request.Method.ToLower().Equals("post"))
{
//请求body
using var ms1 = new MemoryStream();
await request.Body.CopyToAsync(ms1);
var s1 = ms1.ToArray();
var requestBody = Encoding.UTF8.GetString(s1); //把body赋值给bodyStr
_data.Add("request.body", requestBody);
request.Body.Position = 0;
}
else if (request.Method.ToLower().Equals("get"))
{
_data.Add("request.body", request.QueryString.Value);
}
var responseOriginalBody = response.Body;
using var memStream = new MemoryStream();
response.Body = memStream;
#endregion
// 执行其他中间件
await _next(context);
#region 存档response
//处理执行其他中间件后的ResponseBody
memStream.Position = 0;
var responseReader = new StreamReader(memStream);
var responseBody = await responseReader.ReadToEndAsync();
memStream.Position = 0;
await memStream.CopyToAsync(responseOriginalBody);
_data.Add("response.body", responseBody);
_data.Add("response.executeEndTime", DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
#endregion
// 响应完成记录时间和存入日志
context.Response.OnCompleted(() =>
{
_stopwatch.Stop();
_data.Add("elaspedTime", _stopwatch.ElapsedMilliseconds + "ms");
var json = JsonConvert.SerializeObject(_data);
//_logger.Debug(json, "api", request.Method.ToUpper());
return Task.CompletedTask;
});
}
}