.NET 6 HttpLogging RequestBody 在日志中始终为空

Kos*_*tej 9 .net c# logging asp.net-web-api asp.net-core

我使用 HttpLogging 来记录发送到我的端点的请求。我想记录整个请求。我在 Program.cs 中设置 HttpLogging

builder.Services.AddHttpLogging(logging =>
{
    logging.LoggingFields = HttpLoggingFields.All;
});

var app = builder.Build();

// Configure the HTTP request pipeline.

app.UseHttpLogging();
Run Code Online (Sandbox Code Playgroud)

并更改 appsettings.Development.json 中的日志记录级别

 "Microsoft.AspNetCore": "Information"
Run Code Online (Sandbox Code Playgroud)

然后,当我从 Postman 或 cURL 发送请求时,我可以看到所有需要的信息,但 RequestBody始终为空(靠近日志末尾)

info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
      Request:
      Protocol: HTTP/1.1
      Method: POST
      Scheme: https
      PathBase:
      Path: /WeatherForecast
      Accept: */*
      Connection: keep-alive
      Host: localhost:7269
      User-Agent: PostmanRuntime/7.29.0
      Accept-Encoding: gzip, deflate, br
      Content-Type: application/json
      Content-Length: 60
      Postman-Token: [Redacted]
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'WebApplication1.Controllers.WeatherForecastController.Post (WebApplication1)'
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[3]
      Route matched with {action = "Post", controller = "WeatherForecast"}. Executing controller action with signature System.Collections.Generic.IEnumerable`1[WebApplication1.WeatherForecast] Post() on controller WebApplication1.Controllers.WeatherForecastController (WebApplication1).
info: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor[1]
      Executing ObjectResult, writing value of type 'WebApplication1.WeatherForecast[]'.
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
      Response:
      StatusCode: 200
      Content-Type: application/json; charset=utf-8
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2]
      Executed action WebApplication1.Controllers.WeatherForecastController.Post (WebApplication1) in 8.0904ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'WebApplication1.Controllers.WeatherForecastController.Post (WebApplication1)'
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[3]
      RequestBody:   //<----------------------------------------------- ALWAYS EMPTY
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[4]
      ResponseBody: [{"date":"2022-03-17T18:05:11.5799408+01:00","temperatureC":41,"temperatureF":105,"summary":"Bracing"}]
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/1.1 POST https://localhost:7269/WeatherForecast application/json 60 - 200 - application/json;+charset=utf-8 19.0485ms
Run Code Online (Sandbox Code Playgroud)

但是我知道主体在那里,因为当我尝试读取控制器中的主体并在断点处停止时,我可以看到主体加载到变量中。

using var reader = new StreamReader(HttpContext.Request.Body);
var myBody = await reader.ReadToEndAsync(); // {"username": "josef","password": "MyPassword"}
Run Code Online (Sandbox Code Playgroud)

有一个从 PostMan 生成的请求 cURL 示例。

curl --location --request POST 'https://localhost:7269/WeatherForecast' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "josef",
    "password": "MyPassword"
}'
Run Code Online (Sandbox Code Playgroud)

我不知道是否有我错过的步骤或类似的事情。我尝试更改不同的日志级别、不同的请求类型、正文和正文类型。日志中的RequestBody始终为空。

编辑1

我刚刚发现,当我将正文读取器从上面保留在控制器中并从中读取时,它实际上在日志中记录了正确的 RequestBody。有人可以解释这种行为吗?我不明白为什么只有当我手动读取正文时才应该记录。

Sim*_*ell 0

我已经完成了这个工作(尽管上面有 Serilog)。我在我的代码中添加了您的工作内容:

  1. 注册日志记录设置:

    services.AddHttpLogging(logging =>
    {
        logging.LoggingFields = HttpLoggingFields.All;
        logging.RequestHeaders.Add(HeaderNames.Accept);
        logging.RequestHeaders.Add(HeaderNames.ContentType);
        logging.RequestHeaders.Add(HeaderNames.ContentDisposition);
        logging.RequestHeaders.Add(HeaderNames.ContentEncoding);
        logging.RequestHeaders.Add(HeaderNames.ContentLength);
    
        logging.MediaTypeOptions.AddText("application/json");
        logging.RequestBodyLogLimit = 4096;
        logging.ResponseBodyLogLimit = 4096;
    });
    
    Run Code Online (Sandbox Code Playgroud)
  2. 包括一些appsettings.json:

    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft.AspNetCore": "Information",
            "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
        }
     },
Run Code Online (Sandbox Code Playgroud)

可能只需要应用程序设置,尽管logging.MediaTypeOptions.AddText("multipart/form-data");如果您想要记录请求表单提交,您肯定需要编码