【发布时间】:2022-02-16 22:42:17
【问题描述】:
我正在实现一个 API,作为其中的一部分,我设置了一个自定义 .Net 中间件服务扩展 UseRequestLoggingModdlewareExtension(),它在以下之间运行:
app.UseHttpsRedirection();
app.UseRequestLoggingModdlewareExtension();
app.UseRouting();
代码很简单,只是将请求的输出记录到自定义表格中。
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);
}
}
}
}
我正在苦苦挣扎的地方是关于 DBContext 的一些问题的一些错误。
System.InvalidOperationException:在前一个操作完成之前,在此上下文上启动了第二个操作。这通常是由不同的线程同时使用同一个 DbContext 实例引起的。有关如何避免 DbContext 线程问题的更多信息,请参阅https://go.microsoft.com/fwlink/?linkid=2097913。
错误出现了两次,出现在调用 _keyManager 服务的两行。 keyManager 服务只是执行以下操作:
public string getKeyValue(string keyName)
{
var value = _context.keyManagement.Where(k => k.keyName == keyName).Select(v => v.keyValue).FirstOrDefault();
return value;
}
我怀疑这可能与“等待”和代码的异步性有关,但是我尝试了多种组合,似乎无法绕过这个问题。
【问题讨论】:
-
一般来说,初学者的一个常见错误是没有意识到数据库上下文是轻量级对象,应该为每个查询或一组相关查询(可能是会话)创建和销毁数据库.它们不应该长时间徘徊或跨线程使用。考虑这是否是您的问题的原因。 (点击错误消息中的链接。)
-
你能展示你的服务注入配置吗?这可能是由于 keymanager 的作用域造成的,但中间件是单例的。见docs.microsoft.com/en-us/aspnet/core/fundamentals/…
-
异步调用问题。看到这个-stackoverflow.com/questions/44237977/…。同时,尝试对数据库上下文使用
using语句,因为这确认每个打开的数据库连接都已正确关闭。
标签: c# asp.net entity-framework asp.net-web-api dbcontext