先了解core的请求管道
参考博客地址:https://www.cnblogs.com/hippieZhou/p/11205573.html
/// <summary> /// Http 请求中间件 /// </summary> public class HttpContextMiddleware { /// <summary> /// 忽略加密的方法 /// </summary> public static readonly string[] IgnoreToken = { "/user/GetCaptchaImage" }; private readonly RequestDelegate _next;/// <summary> /// 构造 Http 请求中间件 /// </summary> /// <param name="next"></param> public HttpContextMiddleware(RequestDelegate next) { _next = next; } /// <summary> /// 1:将Post方法中Body中的数据进行AES解密 /// 2:将返回数据进行AES加密 /// </summary> /// <param name="context"></param> /// <returns></returns> public async Task Invoke(HttpContext context) { string method = string.Join(",", IgnoreToken.Select(it => it)).ToLower(); if (method.Contains(context.Request.Path.Value.ToLower())) { await _next(context); } context.Request.EnableBuffering(); var api = new ApiRequestInputViewModel { HttpType = context.Request.Method, Query = context.Request.QueryString.Value, RequestUrl = context.Request.Path, RequestName = "", RequestIP = context.Request.Host.Value }; var request = context.Request.Body; var response = context.Response.Body; try { using (var newRequest = new MemoryStream()) { //替换request流 context.Request.Body = newRequest; using (var newResponse = new MemoryStream()) { //替换response流 context.Response.Body = newResponse; //读取原来的流到新的请求处理 using (var reader = new StreamReader(request)) { //读取原始请求流的内容 api.Body = await reader.ReadToEndAsync(); if (string.IsNullOrEmpty(api.Body)) await _next.Invoke(context);// 解密 api.Body = securityHelper.decode(api.Body); } //赋值给原来的流 using (var writer = new StreamWriter(newRequest)) { await writer.WriteAsync(api.Body); await writer.FlushAsync(); newRequest.Position = 0; context.Request.Body = newRequest; await _next(context); } //获取返回参数写回的流 using (var reader = new StreamReader(newResponse)) { newResponse.Position = 0; api.ResponseBody = await reader.ReadToEndAsync(); if (!string.IsNullOrWhiteSpace(api.ResponseBody)) { //api.ResponseBody = api.ResponseBody; api.ResponseBody = securityHelper.encryption(api.ResponseBody); } } //将返回的Response流Copy到原始流,写会流会有字节错误,重新写这个参数 var dataByte = Encoding.Default.GetBytes(api.ResponseBody); //context.Response.ContentType = "application/ison"; context.Response.Headers.Remove("Content-Length"); context.Response.Headers.Add("Content-Length", new[] { dataByte.Length.ToString() }); //await originalResponsestream.WriteAsync (dataByte,0, dataByte. Length); //context. Response.Body = originalResponsestream //把处理好的流写回去 using (var writer = new StreamWriter(response)) { await writer.WriteAsync(api.ResponseBody); await writer.FlushAsync(); } //var response2 = context.Response;//await response2.WriteAsync(api.ResponseBody); //if (!context.Response.HasStarted) //{ // await context.Response.WriteAsync(api.ResponseBody); // //context.Response.Body = response; //} } } } catch (Exception ex) { Console.Write(ex); } finally { context.Request.Body = request; context.Response.Body = response; } // 响应完成时存入缓存 context.Response.OnCompleted(() => { return Task.CompletedTask; }); } private async Task<string> FormatResponse(HttpResponse response) { response.Body.Seek(0, SeekOrigin.Begin); var text = await new StreamReader(response.Body).ReadToEndAsync(); response.Body.Seek(0, SeekOrigin.Begin); return $"{text}"; } }
/// <summary> /// 请求参数加密 /// </summary> public static class MiddlewareExtensions { public static IApplicationBuilder UseHttpContextMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<HttpContextMiddleware>(); } }
封装的保存请求
/// <summary> /// 处理请求参数 /// </summary> public class ApiRequestInputViewModel { /// <summary> /// 请求接口名称 /// </summary> public string RequestName { get; set; } /// <summary> /// 请求来源IP /// </summary> public string RequestIP { get; set; } /// <summary> /// 请求路径 /// </summary> public string RequestUrl { get; set; } /// <summary> /// 请求类型:GET/POST /// </summary> public string HttpType { get; set; } /// <summary> /// 请求参数字符串 /// </summary> public string Query { get; set; } /// <summary> /// 请求报文,POST专用 /// </summary> public string Body { get; set; } public string RequestTime { get; set; } public string ResponseBody { get; set; } public long ElapsedTime { get; set; } public ApiRequestInputViewModel() { this.RequestName = string.Empty; this.RequestIP = string.Empty; this.RequestUrl = string.Empty; this.HttpType = string.Empty; this.Query = string.Empty; this.RequestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); this.Body = string.Empty; this.ResponseBody = string.Empty; this.ElapsedTime = -1; } }
使用方式
app.UseHttpContextMiddleware();
服务还有配置同步写的
services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true) .Configure<IISServerOptions>(x => x.AllowSynchronousIO = true);
处理参数基本完成