.Net 6 API 在数据库中保存请求和响应日志

.Net 6 API save request and reponse log in database

我需要将我的请求和响应 JSON 保存在数据库中,到目前为止我还没有找到任何代码可以这样做。

在较旧的 .net 核心版本中,我使用以下代码读取正文:

context.Request.EnableRewind();

但似乎此代码在 .Net 6 中不起作用,或者我不知道使用它的技巧,这是我最后一个能够读取响应但请求始终为空的代码。

public class APILogFilter : IActionFilter
{
    public async void OnActionExecuted(ActionExecutedContext context)
    {
        string RequestBody = "";
        context.HttpContext.Request.EnableBuffering();
        using (StreamReader reader = new StreamReader(context.HttpContext.Request.Body, Encoding.UTF8, true, 1024, true))
        {
            RequestBody = await reader.ReadToEndAsync();
        };

        string ResultBody = "";
        if (context.Result is ObjectResult)
        {
            var objResult = (ObjectResult)context.Result;
            ResultBody = HelperConvert.GetJSONSerialize(objResult.Value);
        }
        //Save request and response in database 
    }
    public void OnActionExecuting(ActionExecutingContext context)
    {

    }
}

希望有人能帮帮我。

我可以建议您使用 Middleware 而不是过滤器。

这个中间件在 .NET 6 上运行良好。

public class BodyLoggerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<BodyLoggerMiddleware> _logger;

    public BodyLoggerMiddleware(RequestDelegate next, ILogger<BodyLoggerMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task Invoke(HttpContext context)
    {
        
        try
        {
            string requestBody;
            context.Request.EnableBuffering();
            using (StreamReader reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, true))
            {
                requestBody = await reader.ReadToEndAsync();
            }
            _logger.LogInformation("Request: {Request}", requestBody);
        }
        finally
        {
            context.Request.Body.Position = 0;
        }
       

        Stream originalBody = context.Response.Body;

        try
        {
            using (var memStream = new MemoryStream())
            {
                context.Response.Body = memStream;

                await _next(context);

                memStream.Position = 0;
                string responseBody = new StreamReader(memStream).ReadToEnd();
                _logger.LogInformation("Response: {Response}", responseBody);
                memStream.Position = 0;
                await memStream.CopyToAsync(originalBody);
            }
        }
        finally
        {
            context.Response.Body = originalBody;
        }
    }
}