ASP.NET Core Identity UserManager.IsInRole Вызов работает в 2.2, но бросает InvalidOperation в 3.0 - PullRequest
0 голосов
/ 28 октября 2019

У меня есть 2 решения, которые используют ASP.NET Core Identity. Один v.2.2 другой 3.0. Они делают вызовы UserManager.IsInRole (пользователь, role.Name). Код работает в v.2.2, но выдает исключение: «InvalidOperationException: уже существует открытый DataReader, связанный с этой командой, который должен быть закрыт первым». в версии 3.0. Они оба создают два списка пользователей, один из которых находится в целевой роли, а другой - пользователь НЕ в целевой роли. Идея состоит в том, чтобы добавить или удалить пользователей из целевой роли.

Я искал здесь, документацию Microsoft и некоторые блоги, но, похоже, ничто не решает мою проблему

Вот код ввопрос:

    public async Task<IActionResult> OnGetAsync(string id)
    {
        IdentityRole role = await roleManager.FindByIdAsync(id);
        List<FREEIncUser> members = new List<FREEIncUser>();
        List<FREEIncUser> nonMembers = new List<FREEIncUser>();
        foreach (FREEIncUser user in userManager.Users)
        {
            var list = await userManager.IsInRoleAsync(user, role.Name) ? members : nonMembers;
            list.Add(user);
        } // end foreach (FREEIncUser user in userManager.Users)

        RoleUserViewModel = new RoleUserViewModel
        {
            Role = role,
            Members = members,
            NonMembers = nonMembers
        };

        return Page();
    } // end public async Task<IActionResult> OnGetAsync(string id)

Вот несколько скриншотов: v.2.2 Invoke ManageUsers for a role(v.2.2)

Что дает: List of users in and not in role

v.3.0 Invoke ManageUsers for a role(v.3.0)]

Создается исключение: необработанное исключение произошло при обработке запроса. InvalidOperationException: уже существует открытый DataReader, связанный с этой Командой, который должен быть закрыт первым.

Microsoft.Data.SqlClient.SqlCommand + <> c.b__164_0 (результат задачи)

Stack Query Cookies Headers Routing 

InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.
    Microsoft.Data.SqlClient.SqlCommand+<>c.<ExecuteDbDataReaderAsync>b__164_0(Task<SqlDataReader> result)
    System.Threading.Tasks.ContinuationResultTaskFromResultTask<TAntecedentResult, TResult>.InnerInvoke()
    System.Threading.Tasks.Task+<>c.<.cctor>b__274_0(object obj)
    System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, object state)
    System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref Task currentTaskSlot, Thread threadPoolThread)
    Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
    Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
    Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
    Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor+AsyncQueryingEnumerable<T>+AsyncEnumerator.MoveNextAsync()
    System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>.GetResult()
    Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync<TSource>(IAsyncEnumerable<TSource> asyncEnumerable, CancellationToken cancellationToken)
    Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync<TSource>(IAsyncEnumerable<TSource> asyncEnumerable, CancellationToken cancellationToken)
    Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore<TUser, TRole, TContext, TKey, TUserClaim, TUserRole, TUserLogin, TUserToken, TRoleClaim>.IsInRoleAsync(TUser user, string normalizedRoleName, CancellationToken cancellationToken)
    Microsoft.AspNetCore.Identity.UserManager<TUser>.IsInRoleAsync(TUser user, string role)
    FREEInc.WebUI.Pages.RoleAdmin.ManageUsersModel.OnGetAsync(string id) in ManageUsers.cshtml.cs

                    var list = await userManager.IsInRoleAsync(user, role.Name) ? members : nonMembers;
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+GenericTaskHandlerMethod.Convert<T>(object taskAsObject)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+GenericTaskHandlerMethod.Execute(object receiver, object[] arguments)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

TheБросок линии:

var list = await userManager.IsInRoleAsync(user, role.Name) ? members : nonMembers;

Любая помощь и руководство будет принята с благодарностью. Спасибо.

Ответы [ 2 ]

0 голосов
/ 05 ноября 2019

Пост от Kahbazi решил проблему.

0 голосов
/ 04 ноября 2019

попробуйте этот код

foreach (FREEIncUser user in userManager.Users.ToList())
{
    var list = await userManager.IsInRoleAsync(user, role.Name) ? members : nonMembers;
    list.Add(user);
}

Проблема в том, что вы не можете иметь несколько соединений одновременно на DbContext, а когда у вас есть foreach на userManager.Users, соединение открыто изаписи возвращаются одна за другой, и у вас может быть другой запрос (IsInRole) к тому же DbContext.

Добавляя ToList() к userManager.Users, вы получаете всех пользователей и повторяетеим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...