无法访问 ASP.NET Core 3.1 异常处理程序中的 HTTP 请求正文内容
Unable to access HTTP request body content in ASP.NET Core 3.1 exception handler
似乎 .NET Core 3.1 使得在异常后访问原始 HTTP 请求正文变得非常困难
问题的核心似乎是您无法将流倒回到开头以便可以阅读整个内容
在下面的示例中,输出是:
Content-Length: 19
Can't rewind body stream. Specified method is not supported.
Body:
如果我删除 Seek,也不例外,但是 body 当然会返回一个空字符串,因为它已经被处理过
围绕管道 API 有一些新管道涉及 Request.BodyReader,但它们遇到同样的问题。
发生异常后,我需要做的就是将完整的请求转储到包含正文内容的日志文件中。应该不会这么难吧?
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
Console.WriteLine("Content-Length: " + context.Request.Headers["Content-Length"]);
string tmp;
try
{
context.Request.Body.Seek(0, SeekOrigin.Begin);
}
catch(Exception ex)
{
Console.WriteLine("Can't rewind body stream. " + ex.Message);
}
using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8))
{
tmp = await reader.ReadToEndAsync();
}
Console.WriteLine("Body: " + tmp);
});
});
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapDefaultControllerRoute();
});
}
请查看answer by Stephen Wilkinson
将以下内容添加到您的代码中:
Startup.cs
app.Use((context, next) =>
{
context.Request.EnableBuffering(); // calls EnableRewind() `https://github.com/dotnet/aspnetcore/blob/4ef204e13b88c0734e0e94a1cc4c0ef05f40849e/src/Http/Http/src/Extensions/HttpRequestRewindExtensions.cs#L23`
return next();
});
然后您应该能够按照上面的 倒带:
string tmp;
try
{
context.Request.Body.Seek(0, SeekOrigin.Begin);
}
catch(Exception ex)
{
Console.WriteLine("Can't rewind body stream. " + ex.Message);
}
using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8))
{
tmp = await reader.ReadToEndAsync();
}
似乎 .NET Core 3.1 使得在异常后访问原始 HTTP 请求正文变得非常困难
问题的核心似乎是您无法将流倒回到开头以便可以阅读整个内容
在下面的示例中,输出是:
Content-Length: 19
Can't rewind body stream. Specified method is not supported.
Body:
如果我删除 Seek,也不例外,但是 body 当然会返回一个空字符串,因为它已经被处理过
围绕管道 API 有一些新管道涉及 Request.BodyReader,但它们遇到同样的问题。
发生异常后,我需要做的就是将完整的请求转储到包含正文内容的日志文件中。应该不会这么难吧?
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
Console.WriteLine("Content-Length: " + context.Request.Headers["Content-Length"]);
string tmp;
try
{
context.Request.Body.Seek(0, SeekOrigin.Begin);
}
catch(Exception ex)
{
Console.WriteLine("Can't rewind body stream. " + ex.Message);
}
using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8))
{
tmp = await reader.ReadToEndAsync();
}
Console.WriteLine("Body: " + tmp);
});
});
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapDefaultControllerRoute();
});
}
请查看answer by Stephen Wilkinson
将以下内容添加到您的代码中:
Startup.cs
app.Use((context, next) =>
{
context.Request.EnableBuffering(); // calls EnableRewind() `https://github.com/dotnet/aspnetcore/blob/4ef204e13b88c0734e0e94a1cc4c0ef05f40849e/src/Http/Http/src/Extensions/HttpRequestRewindExtensions.cs#L23`
return next();
});
然后您应该能够按照上面的
string tmp;
try
{
context.Request.Body.Seek(0, SeekOrigin.Begin);
}
catch(Exception ex)
{
Console.WriteLine("Can't rewind body stream. " + ex.Message);
}
using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8))
{
tmp = await reader.ReadToEndAsync();
}