UserManager.GetClaimsAsync() 失败 - 连接已关闭

问题描述 投票:0回答:1

在 Blazor InteractiveServer 应用程序中,使用 ASP.NET 身份库,我调用: Microsoft.AspNetCore.Identity.UserManager`1.GetClaimsAsync(TUser 用户)

我通过在 Program.cs 中添加它来将其设置为使用我的扩展类

builder.Services.AddScoped<AuthenticationStateProvider, ExAuthenticationStateProvider>();

除了添加该行之外,对此的所有使用都是 Blazor 堆栈在选择时调用它。我唯一一次在这个类中直接调用任何东西是当我调用

ResetNextCheck()
时。

它抛出(下面是完整的堆栈跟踪)。

Microsoft.EntityFrameworkCore.Query - An exception occurred while iterating over the results of a query for context type 'LouisHowe.web.Areas.Identity.Data.UserDbContext'.
System.InvalidOperationException: Invalid operation. The connection is closed.

索赔表有 34 个条目,因此如果有要求(没有要求),读取整个表会很快。

我的应用程序中所有这些的一个非标准部分是我有

class ExIdentityUser : IdentityUser
,我在其中添加了
public bool Enabled { get; set; }
。所以我的 DbContext 是
UserDbContext : IdentityDbContext<ExIdentityUser>

这发生在我的

ExAuthenticationStateProvider : ServerAuthenticationStateProvider
GetAuthenticationStateAsync()
方法中。

为什么会在这次通话中关闭连接?

完整日志:

Error 08:52:21 [] Microsoft.EntityFrameworkCore.Database.Command - Failed executing DbCommand (19ms) [Parameters=[@__user_Id_0='?' (Size = 450)], CommandType='Text', CommandTimeout='30']
SELECT [a].[Id], [a].[ClaimType], [a].[ClaimValue], [a].[UserId]
FROM [AspNetUserClaims] AS [a]
WHERE [a].[UserId] = @__user_Id_0

// 20 irrelevant log messages

Error 08:52:22 [] Microsoft.EntityFrameworkCore.Query - An exception occurred while iterating over the results of a query for context type 'LouisHowe.web.Areas.Identity.Data.UserDbContext'.
System.InvalidOperationException: Invalid operation. The connection is closed.
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync() InvalidOperationException: Invalid operation. The connection is closed.
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
Error 08:52:22 [] LouisHowe.web.Services.ExAuthenticationStateProvider - GetAuthenticationStateAsync() exception: Invalid operation. The connection is closed. InvalidOperationException: Invalid operation. The connection is closed.
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserOnlyStore`6.GetClaimsAsync(TUser user, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Identity.UserManager`1.GetClaimsAsync(TUser user)
   at LouisHowe.web.Services.ExAuthenticationStateProvider.GetAuthenticationStateAsync() in D:\a\LouisHowe\LouisHowe\LouisHowe.web\Services\ExAuthenticationStateProvider.cs:line 94
asp.net-core blazor asp.net-identity blazor-server-side
1个回答
0
投票

我修复了它(解释如下)。话虽如此,我不知道为什么会解决这个问题。

我用

UserManager<ExIdentityUser>
打电话:

userManager.FindByIdAsync(id);
userManager.GetClaimsAsync(user);

这些调用有时会失败,因为底层 DbConnection 已关闭。我不知道为什么,特别是有时对

FindByIdAsync()
的调用会成功,然后紧接着对
GetClaimsAsync()
的调用将具有关闭的连接。

为了解决这个问题,我将其更改为使用:

IDbContextFactory UserDbFactory; var dbContext = 等待 UserDbFactory.CreateDbContextAsync(); var user = wait dbContext.Users.Where(u => u.Id == id).FirstOrDefaultAsync(); var list = wait dbContext.UserClaims.Where(uc => uc.UserId == id).ToListAsync();

这不仅解决了我的 DbConnection 有时被关闭的问题,还解决了这个问题。正如我上面所说,不知道为什么。但是调用

UserManager
方法会导致
NotifyAuthenticationStateChanged()
失败。切换到
UserDbFactory
解决了这个问题以及其他问题。

© www.soinside.com 2019 - 2024. All rights reserved.