IAsyncActionFilter,尝试记录请求正文,但它是空的

Dav*_*ldo 8 c# .net-core asp.net-core

我正在尝试设置 IAsyncActionFilter 来记录某些 API 请求的请求正文。但是当我尝试读取正文流时,我每次都会得到空字符串。

这是我的代码: StringContent 始终是一个空字符串,即使 post 请求上有一个 json 正文。

    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        ActionExecutedContext rContext = null;
        string stringContent = string.Empty;

        try
        {
            context.HttpContext.Request.EnableBuffering();
            context.HttpContext.Request.Body.Position = 0;

            using (var reader = new StreamReader(context.HttpContext.Request.Body))
            {
                stringContent = await reader.ReadToEndAsync();

                context.HttpContext.Request.Body.Position = 0;
            }

            rContext = await next();
        }
        catch (Exception)
        {
            throw;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我不想使用中间件,因为我只需要记录一些控制器。

NPN*_*son 11

当 IAsyncActionFilter 执行https://github.com/aspnet/Mvc/issues/5260时,MVC 模型绑定器已读取请求正文。

作为一种快速解决方法,您可以添加

app.Use(next => context =>
        {
            context.Request.EnableBuffering();
            return next(context);
        });
Run Code Online (Sandbox Code Playgroud)

在您的startup.cs中,在调用之前配置()UseEndpoints

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.Use(next => context =>
            {
                context.Request.EnableBuffering();
                return next(context);
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
Run Code Online (Sandbox Code Playgroud)

当然,这将为您的所有请求启用请求正文缓冲,这可能是不可取的。如果是这种情况,您必须向 EnableBuffering 委托添加一些条件逻辑。