Ошибка UserManager.GetClaimsAsync() – соединение закрыто

В приложении 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 : ServerAuthenticationStateProviderGetAuthenticationStateAsync() метода.

Почему при этом вызове закрывается соединение?

Полный журнал:

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

Приводят ли другие запросы к той же ошибке? Приложение по-прежнему работает нормально после получения этой ошибки? Можете ли вы показать точный код, который вам нужен для получения претензий через диспетчер пользователей?

Prolog 01.05.2024 20:17

@HenkHolterman Я добавил, как он внедряется и т. д. Все, что я делаю, это вызов AddScoped() в Program.cs. Когда он вызывается, ожидается и т. д., это Blazor и/или библиотека удостоверений. Я также нашел исправление (добавленное ниже), но понятия не имею, почему это его исправляет, что меня всегда беспокоит. Спасибо

David Thielen 02.05.2024 23:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
81
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я это исправил (объяснение ниже). С учетом сказанного, я не знаю, почему это исправляет.

Я использовал UserManager<ExIdentityUser>, чтобы вызвать:

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

Эти вызовы иногда терпели неудачу, поскольку базовый DbConnection был закрыт. Я понятия не имею, почему, тем более что иногда вызов FindByIdAsync() завершался успешно, тогда следующий вызов GetClaimsAsync() имел бы закрытое соединение.

Чтобы обойти это, я изменил его на использование:

IDbContextFactory<UserDbContext> UserDbFactory;
var dbContext = await UserDbFactory.CreateDbContextAsync();
var user = await dbContext.Users.Where(u => u.Id == id).FirstOrDefaultAsync();
var list = await dbContext.UserClaims.Where(uc => uc.UserId == id).ToListAsync();

Это не только решило мою проблему с иногда закрытием DbConnection, но и решило эту проблему. Как я уже сказал выше, понятия не имею, почему. Но вызов методов UserManager привел к сбою NotifyAuthenticationStateChanged(). Переход на UserDbFactory устранил эту проблему, а также другую проблему.

Другие вопросы по теме