在ASP.net Core中获取压缩的响应长度

编程入门 行业动态 更新时间:2024-10-25 07:27:11
本文介绍了在ASP Core中获取压缩的响应长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我已经使用在Kestrel上运行的 Core构建了RESTful API.我刚刚使用"GzipCompressionProvider"中间件启用了压缩,如此处.

I've build a RESTful API using Core running on Kestrel. I've just enabled compression using "GzipCompressionProvider" middleware as described here.

我还使用了一个自定义记录器,该记录器将所有请求/响应记录到具有如下响应和请求长度的数据库中:

I'm also using a custom logger that logs all requests/responses to a DB with the response and request lengths as per below:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); var provider = new FileExtensionContentTypeProvider(); provider.Mappings[".apk"] = "application/vnd.android.package-archive"; app.UseCors("AllowAll"); app.UseResponseCompression(); app.UseMiddleware<myMiddleware.LoggerMiddleware>(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }

Logger中间件的实现如下:

The implementation of the Logger middleware is as follows:

public LoggerMiddleware(RequestDelegate next, AuditContext dbcontext, IOptions<AppSettings> appsettings, IConfiguration config, ILoggerFactory loggerfactory) { _next = next; dbContext = dbcontext; appSettings = appsettings; _config = config; loggerFactory = loggerfactory; } public async Task Invoke(HttpContext context) { ApiLogEntry apiLog = null; using (MemoryStream requestBodyStream = new MemoryStream()) { using (MemoryStream responseBodyStream = new MemoryStream()) { Stream originalRequestBody = context.Request.Body; context.Request.EnableRewind(); Stream originalResponseBody = context.Response.Body; try { await context.Request.Body.CopyToAsync(requestBodyStream); requestBodyStream.Seek(0, SeekOrigin.Begin); string requestBodyText = new StreamReader(requestBodyStream).ReadToEnd(); requestBodyStream.Seek(0, SeekOrigin.Begin); context.Request.Body = requestBodyStream; string responseBody = ""; context.Response.Body = responseBodyStream; Stopwatch watch = Stopwatch.StartNew(); await _next(context); watch.Stop(); responseBodyStream.Seek(0, SeekOrigin.Begin); responseBody = new StreamReader(responseBodyStream).ReadToEnd(); string appName = "Tracy"; if (context.Request.Headers["tracy-app"] != "") { appName = context.Request.Headers["tracy-app"]; } string token = ""; var authorization = context.Request.Headers["Authorization"].ToString(); if (authorization == "" || !authorization.Contains("Bearer")) { } else { token = authorization.Remove(0, 7).Trim(); } string requestHeaders = string.Join(",", context.Request.Headers.Select(he => he.Key + ":[" + he.Value + "]").ToList()); string responseHeaders = string.Join(",", context.Response.Headers.Select(he => he.Key + ":[" + he.Value + "]").ToList()); apiLog = new ApiLogEntry { Application = appName, Machine = Environment.MachineName, RequestContentType = context.Request.ContentType, RequestRouteTemplate = context.Request.Path, RequestRouteData = requestBodyText, RequestIpAddress = context.Connection.RemoteIpAddress.MapToIPv4().ToString(), RequestMethod = context.Request.Method, RequestHeaders = requestHeaders, RequestTimestamp = DateTime.Now, RequestUri = (context.Request.IsHttps ? "" : "") + context.Request.HttpContext.Request.Host.Value + context.Request.Path, ResponseContentType = context.Response.ContentType, ResponseHeaders = responseHeaders, ResponseStatusCode = context.Response.StatusCode, RequestLength = requestBodyText.Length + requestHeaders.Length, ResponseLength = responseBody.Length + responseHeaders.Length, Duration = watch.ElapsedMilliseconds, SimId = context.Request.Headers["sim-serialnumber"], DeviceId = context.Request.Headers["tracy-deviceid"], ClientAppVersion = context.Request.Headers["app-version"], UserId = dws.tracy.Security.AuthHelpers.GetUserId(appSettings, token) }; if (appSettings.Value.Logging.LogResponse) { apiLog.ResponseContentBody = responseBody; } responseBodyStream.Seek(0, SeekOrigin.Begin); await responseBodyStream.CopyToAsync(originalResponseBody); if (apiLog != null && appSettings.Value.Logging.IsActive) { var apilogDB = Mapper.Map<dws.Data.ApiLogEntry>(apiLog); using (var logContext = new AuditContext(_config.GetConnectionString("DwsContext"))) { var apiLogRepo = new dws.Data.Repositories.ApiLogEntryRepository(logContext); apiLogRepo.Add(apilogDB); apiLogRepo.Commit(); } } } catch (Exception ex) { //ExceptionLogger.LogToDatabse(ex); string innerException = ""; if (ex.InnerException!=null) { innerException = ex.InnerException.Message; } ILogger logger; logger = loggerFactory.CreateLogger("LoggerEntry"); logger.LogCritical(ex.ToString()); logger.LogCritical(innerException); byte[] data = System.Text.Encoding.UTF8.GetBytes("Server error"); context.Response.StatusCode = 500; originalResponseBody.Write(data, 0, data.Length); } finally { context.Request.Body = originalRequestBody; context.Response.Body = originalResponseBody; } } } }

麻烦的是,ResponseLength始终是预压缩长度.关于我需要更改的任何建议.我假设问题是仅在将响应刷新到客户端时才压缩响应?在那之后我可以添加我的记录器吗?

The trouble is that the ResponseLength is always the pre-compression length. Any suggestions on what I need to change. I'm assuming the issue is that the response is being compressed only when it is flushed to the client? Am I able to add my logger after that point?

推荐答案

问题在这里:

app.UseResponseCompression(); app.UseMiddleware<myMiddleware.LoggerMiddleware>();

按照该顺序,响应压缩中间件将被放置在中间件的前面.这意味着压缩中间件将在中间件之前得到请求,而处理响应在中间件之后之后.

With that order, the response compression middleware will be placed in front of your middleware. That means compression middleware will get request before your middleware, but process response after your middleware.

尝试在UseResponseCompression()之前添加中间件,您应该会看到压缩的内容.

Try to add your middleware before UseResponseCompression() and you should see compressed content.

参考: ASP.NET核心中间件管道

更多推荐

在ASP.net Core中获取压缩的响应长度

本文发布于:2023-11-15 19:04:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1597148.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:长度   ASP   net   Core

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!