ASP.NET Core Identity UserManager.IsInRole 调用在 2.2 中有效,但在 3.0 中引发 InvalidOperation
Posted
技术标签:
【中文标题】ASP.NET Core Identity UserManager.IsInRole 调用在 2.2 中有效,但在 3.0 中引发 InvalidOperation【英文标题】:ASP.NET Core Identity UserManager.IsInRole Call Works in 2.2 But Throws InvalidOperation in 3.0 【发布时间】:2020-02-23 08:04:42 【问题描述】:我有 2 个使用 ASP.NET Core Identity 的解决方案。一个是 v.2.2,另一个是 3.0。他们调用 UserManager.IsInRole(user, role.Name)。该代码在 v.2.2 中有效,但会引发异常,“InvalidOperationException:已经有一个打开的 DataReader 与此命令关联,必须先关闭它。”在 v.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
这给出了:
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)
投掷线是:
var list = await userManager.IsInRoleAsync(user, role.Name) ? members : nonMembers;
我们将不胜感激任何帮助和指导。谢谢。
【问题讨论】:
抛出异常时,members.Count
的准确值是多少? nonMembers.Count
?
.NET Core 3解决方案中,成员数为1,非成员数为0。2.2版本中,成员数为1;非会员人数为 4。
【参考方案1】:
将此添加到您的连接字符串:MultipleActiveResultSets=True;
【讨论】:
【参考方案2】:试试这个代码
foreach (FREEIncUser user in userManager.Users.ToList())
var list = await userManager.IsInRoleAsync(user, role.Name) ? members : nonMembers;
list.Add(user);
问题是你不能在DbContext
上同时有多个连接,当你在userManager.Users
上有一个 foreach 时,连接是打开的并且记录一个一个地返回,你可以有另一个查询(IsInRole
)在同一个DbContext
上。
通过将ToList()
添加到userManager.Users
,您将获得所有用户并对其进行迭代。
【讨论】:
这就是答案。我有 foreach (var role in _roleManager.Roles) (await _userManager.IsInRoleAsync(user, role.Name)) "并且在 This mysqlConnection is already in use 上出错。请参阅fl.vu/mysql-conn-reused 将其更改为 foreach (var role在 _roleManager.Roles.ToList()) if (await _userManager.IsInRoleAsync(user, role.Name)) 中,它修复了它以上是关于ASP.NET Core Identity UserManager.IsInRole 调用在 2.2 中有效,但在 3.0 中引发 InvalidOperation的主要内容,如果未能解决你的问题,请参考以下文章
“Identity.External”的 ASP.NET Core 标识异常
ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 14. ASP.NET Core Identity 入门
ASP.Net Core 如何在 EF Core 和 Identity 中获取用户角色