我正在创建一个内部微服务。我将标头中的域用户名传递给我的服务,我想确保无论使用什么用户名传递,无论哪个端点被调用,都存在相应的用户实体。 所以我添加了一个中间件,首先确保头部中存在用户名,并检查用户实体是否存在,如果不存在则创建它。
但是,当我调用多线程服务时,这会给我带来问题: 当我向服务发送多个请求时,服务会抛出一个带有&#34的InvalidOperation异常;附加信息:连接未关闭。连接的当前状态是开放的。"
这是异常转储:
{System.InvalidOperationException:连接未关闭。该 连接的当前状态正在连接。在 System.Data.ProviderBase.DbConnectionClosedConnecting.TryOpenConnection(的DbConnection outerConnection,DbConnectionFactory connectionFactory, TaskCompletionSource
1 retry, DbConnectionOptions userOptions) at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource
1 重试)在System.Data.SqlClient.SqlConnection.Open()处 Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open()
在 Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable.Enumerator.BufferlessMoveNext(布尔 缓冲区) Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerExecutionStrategy.Execute [TState,TResult](Func2 operation, Func
2 verifySucceeded,TState state)at at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider&LT; _ShapedQuery&GT; d__31.MoveNext() at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.<_Include>d__30
1.MoveNext() 在 Microsoft.EntityFrameworkCore.Query.QueryMethodProvider&LT; _Include&GT; d__301.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1 来自)lambda_method(Closure,QueryContext)at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler&LT;。&以及c
我的上下文和存储库注册:
public void ConfigureServices(IServiceCollection services)
{
try
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
var connectionString = Startup.Configuration["connectionStrings:whiteApplicationsDbConnectionString"];
services.AddDbContext<WhiteApplicationContext>(o => o.UseSqlServer(connectionString),ServiceLifetime.Scoped);
services.AddMvc();
services.AddScoped<IWhiteApplicationsRepository, WhiteApplicationsRepository>();
services.AddScoped<IWhiteUserRepository, WhiteUserRepository>();
services.AddScoped<IGroupRepository, GroupRepository>();
services.AddScoped<IDiskUtils, DiskUtils>();
ConfigureAutoMapper();
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
throw;
}
}
这是我注册中间件的方式:
app.UseMiddleware<ActiveDirectoryAuthenticationMiddleware>();
这是我的中间件实现:
public class ActiveDirectoryAuthenticationMiddleware
{
private readonly IWhiteUserRepository _repository;
private readonly RequestDelegate next;
public ActiveDirectoryAuthenticationMiddleware(RequestDelegate next,IWhiteUserRepository _repository)
{
this.next = next;
this._repository = _repository;
}
public async Task Invoke(HttpContext httpContext)
{
if (!httpContext.Request.Headers.ContainsKey("Username"))
{
await ReturnBadRequest(httpContext, "Username");
}
if (!httpContext.Request.Headers.ContainsKey("Fullname"))
await ReturnBadRequest(httpContext, "Fullname");
if (!httpContext.Request.Headers.ContainsKey("MachineName"))
await ReturnBadRequest(httpContext, "MachineName");
var userName = httpContext.Request.Headers["Username"];
var fullName = httpContext.Request.Headers["Fullname"];
var user = _repository.GetUser(userName); //Exception is thrown here
if (user == null)
_repository.CreateUser(new DTOs.WhiteLogin { FullName = fullName, UserName = userName });
await next.Invoke(httpContext);
}
private static async Task ReturnBadRequest(HttpContext httpContext, string missingValue)
{
httpContext.Response.StatusCode = 400;
await httpContext.Response.WriteAsync($"{missingValue} missing");
return;
}
}
此行引发异常:
var user = _repository.GetUser(userName);
这是我的用户存储库实现的一部分:
public class WhiteUserRepository : IWhiteUserRepository, IDisposable
{
private WhiteApplicationContext ctx;
public WhiteUserRepository(WhiteApplicationContext _ctx)
{
this.ctx = _ctx;
}
public void Dispose()
{
ctx.Dispose();
}
public WhiteUser GetUser(string username)
{
var user = ctx.WhiteUsers.Include(x => x.UserGroupWhiteUsers).Include(x => x.UserMachineConnections).FirstOrDefault(x => x.Username == username);
return user;
}
public WhiteUser CreateUser(WhiteLogin whiteLogin)
{
var whiteUser = new WhiteUser { Username = whiteLogin.UserName, FullName = whiteLogin.FullName };
ctx.WhiteUsers.Add(whiteUser);
return whiteUser;
}
如果我删除访问数据库的三行,那么一切正常。 我的用户存储库是作为作用域添加的,我在sql连接字符串上有多个活动结果集,但它仍然无法正常工作。 我还没有找到任何可以解释这种行为的东西..
有什么想法吗?