使用NLogRequestPostedBodyMiddleware记录请求体时遇NotSupportedException异常
解决.NET6中NLog记录请求体抛出System.NotSupportedException的问题
针对你遇到的问题,以下是几个可行的排查和解决方向:
1. 确保请求体可重复读取
.NET6中HttpRequest.Body默认是单向流,一旦被读取就无法再次访问。如果NLog的请求体中间件之前有其他中间件读取了请求体,或者没有启用缓冲,就会抛出NotSupportedException。
解决方法:在所有读取请求体的中间件(包括NLog的)之前,启用请求缓冲:
var builder = WebApplication.CreateBuilder(args); // 配置表单缓冲(针对表单提交场景) builder.Services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(options => { options.BufferBody = true; options.BufferBodyLengthLimit = 10 * 1024 * 1024; // 按需调整缓冲大小 }); // 初始化NLog builder.Logging.ClearProviders(); builder.Logging.SetMinimumLevel(LogLevel.Trace); builder.Host.UseNLog(); var app = builder.Build(); // 添加缓冲中间件,必须在NLog请求体中间件之前 app.Use(async (context, next) => { context.Request.EnableBuffering(); // 重置流位置到开头,确保后续中间件能正常读取 context.Request.Body.Position = 0; await next(); }); // 注册NLog请求体中间件 app.UseMiddleware<NLog.Web.NLogRequestPostedBodyMiddleware>(); // 保持其他中间件顺序正确 app.UseRouting(); app.UseAuthorization(); app.MapControllers(); app.Run();
2. 检查NLog配置的正确性
确保${aspnet-request-post-body}的使用符合要求:
- 若请求体是非UTF8编码,需显式指定编码:
${aspnet-request-post-body:encoding=utf-8} - 避免在不支持的请求类型(如
multipart/form-data大文件上传)中强制读取请求体,可添加条件判断跳过:
<target name="file" xsi:type="File" fileName="${basedir}/logs/${shortdate}.log"> <layout> ${longdate} | ${level} | ${when:when='${aspnet-request-content-type}' contains 'application/json':inner=${aspnet-request-post-body}:else='Skipped non-JSON body'} </layout> </target>
3. 升级NLog.Web.AspNetCore版本
你使用的5.3.1版本属于较旧版本,可能存在.NET6适配缺陷。建议升级到最新稳定版(如5.26.x及以上),新版本针对.NET6+的请求体读取逻辑做了优化,能有效减少此类异常。
异常栈辅助排查
如果异常栈指向HttpRequest.Body的读取操作(如StreamReader.ReadToEndAsync或Stream.Seek),则核心问题就是流无法重复读取,此时优先检查缓冲配置是否生效。
内容的提问来源于stack exchange,提问作者Ching Wang
相关产品推荐
相关产品推荐

