You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#极简Web API:是否需EnableBuffering?如何记录无效请求内容?

解决ASP.NET Core极简API中记录无效请求内容的问题

是否需要调用EnableBuffering()?

是必须的。默认情况下ASP.NET Core的请求体流只能读取一次,且POST这类带请求体的请求流默认不支持回溯。调用EnableBuffering()会将请求体缓存到内存或磁盘,允许我们完整读取流内容,避免因流已被消费而无法获取请求体的问题。

中间件修改实现完整请求记录

以下是集成日志逻辑的修改方案(以内置ILogger为例):

首先,在构建应用时添加基础日志服务(极简场景下可直接用控制台日志):

var builder = WebApplication.CreateBuilder(args);
// 添加控制台日志(可替换为Serilog等第三方日志库)
builder.Logging.AddConsole();
var app = builder.Build();

// 原有静态文件、HSTS等配置代码保持不变

然后修改拦截无效请求的中间件:

app.Use(async (context, next) =>
{
    // 从请求服务容器中获取日志实例
    var logger = context.RequestServices.GetRequiredService<ILogger<Program>>();
    
    if (context.Request.Method.Equals("GET", StringComparison.InvariantCultureIgnoreCase) && 
        !context.Request.Path.Value!.Contains("."))
    {
        await next();
    }
    else
    {
        context.Response.StatusCode = (int)HttpStatusCode.GatewayTimeout;

        // 启用请求体缓冲,允许多次读取流
        context.Request.EnableBuffering();

        // 收集请求头信息
        var headerLog = string.Join(Environment.NewLine,
            context.Request.Headers.Select(h => $"{h.Key}: {string.Join(", ", h.Value)}"));

        // 收集请求体信息
        string bodyLog = string.Empty;
        if (context.Request.Body.CanRead)
        {
            // 将流指针重置到起始位置
            context.Request.Body.Position = 0;
            // leaveOpen: true 避免关闭流,保持规范
            using var reader = new StreamReader(context.Request.Body, leaveOpen: true);
            bodyLog = await reader.ReadToEndAsync();
            // 重置流指针,兼容后续可能的读取操作
            context.Request.Body.Position = 0;
        }

        // 构造完整日志内容
        var logMessage = $@"
=== 无效请求详情 ===
请求方法: {context.Request.Method}
请求路径: {context.Request.Path}
查询字符串: {context.Request.QueryString}
请求头:
{headerLog}
请求体:
{bodyLog}
===================";

        // 写入日志(可根据需求调整日志级别,如LogError)
        logger.LogWarning(logMessage);
    }
});

关键注意事项

  • EnableBuffering()必须在读取请求体之前调用,否则会抛出流无法读取的异常。
  • 处理超大请求体时,可使用EnableBuffering(int bufferThreshold)设置内存缓存阈值,超过阈值的内容会写入临时文件,避免内存溢出。
  • 可根据需求过滤日志中的敏感信息,比如Authorization请求头、请求体中的隐私数据。

内容的提问来源于stack exchange,提问作者Wim ten Brink

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 19:15:52