简体   繁体   English

在 ASP.Net Core 中压缩之前记录响应正文

[英]Logging response body BEFORE compression in ASP.Net Core

I have a seemingly simple thing that I need to do;我有一件看似简单的事情需要做; log the response body from middleware AFTER it has been fully formed by controllers but BEFORE compression is applied.在控制器完全形成响应体之后,但在应用压缩之前,记录来自中间件的响应体。

The problem here is that I am only able to read a response after awaiting next() from the logging middleware, which also compresses the response body.这里的问题是我只能在等待来自日志记录中间件的 next() 之后读取响应,这也压缩了响应正文。

My logging implementation is based on this article;我的日志实现基于这篇文章; https://elanderson.net/2019/12/log-requests-and-responses-in-asp-net-core-3/?unapproved=220252&moderation-hash=337bbb1489547696340e7506459779ba#comment-220252 https://elanderson.net/2019/12/log-requests-and-responses-in-asp-net-core-3/?unapproved=220252&moderation-hash=337bbb1489547696340e7506459779ba#comment-220252

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
    app.UseMiddleware<RequestResponseLoggingMiddleware>();

    app.UseRouting();

    //compression
    app.UseResponseCompression();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints => {
        endpoints.MapControllers();
    });

    ConfigurePSTZone();
...
}

RequestResponseLoggingMiddleware middleware; RequestResponseLoggingMiddleware 中间件;

    var originalBodyStream = context.Response.Body;
    await using var responseBody = _recyclableMemoryStreamManager.GetStream();
    context.Response.Body = responseBody;
    await _next(context); 
    context.Response.Body.Seek(0, SeekOrigin.Begin);
    var responseBody = await new StreamReader(context.Response.Body).ReadToEndAsync();

If you call await _next(context);如果你调用await _next(context); then responseBody will be filled with the compressed response after.然后 responseBody 将填充压缩后的响应。 If you dont call it, responseBody will be empty.如果你不调用它, responseBody 将为空。 Even if you move the UseMiddleware();即使你移动了UseMiddleware(); to the very end of Configure.到配置的最后。

Not sure there is actually a solution for this currently in .Net 5, but hey maybe someone has figured it out.不确定当前在 .Net 5 中实际上是否有解决方案,但嘿,也许有人已经想通了。

Thanks谢谢

ADDED NOTE: This seems to only be a problem when using Asp.Net with kestrel (linux based).补充说明:这似乎只是在使用带有 kestrel(基于 linux)的 Asp.Net 时出现问题。 On windows you dont need response compression middleware.. so I guess not a lot of people have switched to Linux yet which is why nobody has asked this question before.在 Windows 上你不需要响应压缩中间件..所以我想没有多少人已经切换到 Linux 这就是为什么之前没有人问过这个问题。 Jeepers吉普车

Middlewares are executed in order ( link ).中间件按顺序执行( 链接)。
You can move app.UseMiddleware<RequestResponseLoggingMiddleware>();你可以移动app.UseMiddleware<RequestResponseLoggingMiddleware>(); call after app.UseResponseCompression();app.UseResponseCompression();之后调用app.UseResponseCompression();

I had faced the same issue while using the .net core inbuilt ResponseCompression, but was able to use the inspiration from CompressionMiddleware.cs to create a custom compression middleware我在使用 .net 核心内置 ResponseCompression 时遇到了同样的问题,但能够使用来自CompressionMiddleware.cs的灵感来创建自定义压缩中间件

And Configure in Startup.cs is as follows并且在Startup.cs中配置如下

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
    {
        app.UseCompression();
        
        app.UseMiddleware<RequestResponseLogger>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM