I am implementing an API and as part of it I have setup a custom .Net Middleware service extension UseRequestLoggingModdlewareExtension() that it run between the following:
app.UseHttpsRedirection();
app.UseRequestLoggingModdlewareExtension();
app.UseRouting();
The code is simple, and just logs the output of the request into a custom table.
public async Task InvokeAsync(HttpContext httpContext)
{
var stopAccess = _keyManager.getKeyValue("stopImmediateAccess");
if (!Convert.ToBoolean(stopAccess))
{
await _next(httpContext);
var loggingLevel = _keyManager.getKeyValue("loggingLevel");
if (loggingLevel != null)
{
if (loggingLevel.ToLower() == "information")
{
var userIdClaim = httpContext.User.FindFirst("userid")?.Value;
int? userId = null;
if(userIdClaim != null)
{
userId = Int32.Parse(userIdClaim);
}
var logging = new ApiRequestLogging
{
userId = userId,
remoteIp = httpContext.Connection.RemoteIpAddress.ToString() == "::1" ? "localhost" : httpContext.Connection.RemoteIpAddress.ToString(),
userAgent = httpContext.Request.Headers["User-Agent"].ToString(),
requestMethod = httpContext.Request.Method,
requestUrl = httpContext.Request.Path,
queryString = httpContext.Request.QueryString.ToString(),
requestHeaders = String.Join(",", httpContext.Request.Headers),
responseCode = httpContext.Response.StatusCode,
responseHeaders = String.Join(",", httpContext.Response.Headers),
createdDt = DateTime.Now
};
_logging.LogApiRequest(logging);
}
}
}
}
Where I am struggling is with some errors regarding some issues with the DBContext.
System.InvalidOperationException: A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
The error is appearing twice, at both lines where the _keyManager service is called. The keyManager service is simply doing the following:
public string getKeyValue(string keyName)
{
var value = _context.keyManagement.Where(k => k.keyName == keyName).Select(v => v.keyValue).FirstOrDefault();
return value;
}
I have a suspicion that it could be something to do with the 'await' and the aschronousness of the code, however I have tried multiple combinations and cannot seem to bypass this issue.
usingstatement for db context as this confirms every db connection opened is closed properly.