In my .NET Core 3.1 app I need to log out any requests with a status code greater than 400 on my controller POST action.
To do this I have created the following ResultFilterAttribute
public class LogFailureResponseFilter : ResultFilterAttribute
{
private readonly ILogger _logger;
public LogFailureResponseFilter(ILogger<LogFailureResponseFilter> logger)
{
_logger = logger;
}
public override void OnResultExecuted(ResultExecutedContext context)
{
var statusCode = context.HttpContext.Response.StatusCode;
if (statusCode >= 400)
{
using var reader = new StreamReader(context.HttpContext.Request.Body);
var body = reader.ReadToEndAsync().Result; // <--- this is always null
_logger.LogWarning($"Request failed for route path {context.HttpContext.Request.Path} with status code {statusCode}. The payload was {body}");
}
base.OnResultExecuted(context);
}
}
I have enabled buffering as per this Stack Overflow post that describes how to re-read a request body in Startup.cs
as follows:
app.Use(async (context, next) => {
context.Request.EnableBuffering();
await next();
});
Whenever I try to read the body it is always null - can anyone help please?
Edit: I've attempted to seek to the beginning of the stream with the following code but it results in System.NotSupportedException
var bodyStream = context.HttpContext.Request.Body;
bodyStream.Seek(0, SeekOrigin.Begin);
using var reader = new StreamReader(bodyStream);
var body = reader.ReadToEndAsync().Result;