Im trying to set up IAsyncActionFilter to log request body for some API requests. But when I try to read body stream I get empty string every time.
Here is my code: StringContent is always an empty string, even tho there is an json body on post requests.
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;
}
}
I dont want to use middleware, becouse I need to log only some of the controllers.
The request body has already been read by the MVC model binder by the time your IAsyncActionFilter executes https://github.com/aspnet/Mvc/issues/5260.
As a quick workaround, you could add
app.Use(next => context =>
{
context.Request.EnableBuffering();
return next(context);
});
in your startup.cs Configure() BEFORE your UseEndpoints call
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();
});
}
Of course, this would enable request body buffering for all of your requests, which may not be desirable. If that's the case, you would have to add some conditional logic to the EnableBuffering delegate.