我在我的ASP .NET核心應用程序中實現了一個cookie身份驗證模塊作爲中間件。我收到一個錯誤「InvalidOperationException:在上一個操作完成之前,在此上下文中啓動了第二個操作,但不保證所有實例成員都是線程安全的。」兩個請求幾乎同時發生(在函數CheckToken中)。我相信每個請求都應該收到一個單獨的數據庫上下文,所以我不明白爲什麼會發生此錯誤。異步實體框架數據庫訪問失敗,例外(ASP .NET核心)
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
// ...
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// ...
app.UseTeamAuthentication();
// ...
中間件
namespace Team
{
public static class TeamExtensions
{
public static IApplicationBuilder UseTeamAuthentication(this IApplicationBuilder builder)
{
return builder.UseMiddleware<TeamAuthentication>();
}
}
public class TeamAuthentication
{
private readonly RequestDelegate next;
private readonly ApplicationDbContext db;
public TeamAuthentication(RequestDelegate _next, ApplicationDbContext _db)
{
next = _next;
db = _db;
}
public async Task Invoke(HttpContext context)
{
bool Authenticated = false;
bool Login = (context.Request.Path == "/Login");
string TokenContent = context.Request.Cookies["t"];
if (!Login && TokenContent != null)
{
int UserID = await Security.CheckToken(db, TokenContent);
if (UserID > 0)
{
Authenticated = true;
}
}
if (Login || Authenticated)
{
await next.Invoke(context);
}
else
{
context.Response.StatusCode = 401;
if (context.Request.Headers["X-Requested-With"] != "XMLHttpRequest")
{
await context.Response.WriteAsync("No access!");
}
}
}
}
}
CheckToken
public async static Task<int> CheckToken(ApplicationDbContext db, string Content)
{
var token = await db.Token.FirstOrDefaultAsync(m => m.Content == Content);
if (token != null)
{
if (DateTime.Now < token.Expiry)
{
token.Expiry = DateTime.Now.AddHours(1);
await db.SaveChangesAsync();
return token.UserID;
}
else
{
db.Token.Remove(token);
await db.SaveChangesAsync();
return 0;
}
}
else
{
return 0;
}
}
好吧,如果是這樣的話,就不會(功能)DB: - (每個DI一次範圍更精確)這裏面的代碼
Invoke
方法相反,獲得獨立的DbContext爲每個請求在中間件訪問是不可能的?中間件身份驗證如何在這種情況下工作? – Marko
我認爲這是可能的。嘗試添加依賴到'Invoke'方法中,而不是構造函數,比如'public async Task Invoke(HttpContext context,ApplicationDbContext db)' –