I have a ASP.NET Core 6 REST API application, installed on the on-premise server with IIS. In one of the environments, about 20% of queries fail due to an empty HttpContext.Response.Body object. I use Audit.NET for logging requests and responses. Audit.NET response log looks like this:
"Action": {
"HttpMethod": "POST",
"ResponseStatus": "OK",
"ResponseStatusCode": 200,
"ResponseBody": {
"Type": "application/json; charset=utf-8",
"Value": ""
}
}
The problem is similar to this https://github.com/aws/aws-lambda-dotnet/issues/1457, but I don't use AWS.
I suspect that the problem may be caused by the use of Audit.Net, but analyzing the code of the added middleware, I cannot find the cause of the error.
Has anyone encountered such a problem?
I tried mass testing on local environments but failed to reproduce the reported issue.
EDIT 21.08.2023: My code looks like this:
Program.cs
var app = builder.Build();
app.Use((context, next) =>
{
context.Request.EnableBuffering();
return next();
});
app.UseExceptionHandler(GlobalExceptionHandler.Configure);
app.UseAuditMiddleware(_ => _
.FilterByRequest(r => r.Path.Value?.Contains("/api/") == true)
.WithEventType(context => context.Request.Path)
.IncludeRequestBody()
.IncludeResponseBody());
app.UseMiddleware<ExceptionHandlingMiddleware>();
app.UseSwagger();
app.MapControllers();
GlobalExceptionHandler.cs
internal class GlobalExceptionHandler
{
public static void Configure(IApplicationBuilder applicationBuilder)
{
applicationBuilder.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
context.Response.ContentType = "application/json";
var status = context.Features.Get<IStatusCodeReExecuteFeature>();
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
var responseDetails = GetFullExceptionDetails(status, error.Error);
await context.Response.WriteAsync(responseDetails, Encoding.UTF8);
}
});
}
}
ExceptionHandlingMiddleware.cs
internal class ExceptionHandlingMiddleware
{
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch (Exception ex)
{
var errorResponse = HandleBusinessException(exception as MyException);
var statusCode = GetStatusCode(exception as MyException);
context.Response.StatusCode = statusCode;
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(errorResponse.Serialize());
}
}
}