【问题标题】:Unable to access HTTP request body content in ASP.NET Core 3.1 exception handler无法访问 ASP.NET Core 3.1 异常处理程序中的 HTTP 请求正文内容
【发布时间】:2020-08-21 23:26:35
【问题描述】:

似乎 .NET Core 3.1 使得在出现异常后访问原始 HTTP 请求正文变得非常困难

问题的核心似乎是您无法将流倒回到开头,因此可以阅读整个内容

在下面的示例中,输出为:

Content-Length: 19
Can't rewind body stream. Specified method is not supported.
Body:

如果我删除了 Seek,也不例外,但是body当然会作为一个空字符串返回,因为它已经被处理了

有一些基于 Pipeline 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();
        });
    }

【问题讨论】:

  • 为什么需要在异常时重复读取请求正文。
  • 很多用例 - 记录一个。您想知道请求失败时的样子。安全性 - 如果是恶意的,其中可能包含对跟踪等有用的信息。尝试捕获异常内容非常有意义。

标签: asp.net-core-3.1


【解决方案1】:

请通过Stephen Wilkinson查看answer

将以下内容添加到您的代码中:

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();
});

然后您应该能够按照上面的code 倒带:

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();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    相关资源
    最近更新 更多