【问题标题】:Microsoft Identity Framework assigning roles to user error with Postgres Database - The CancellationTokenSource has been disposedMicrosoft Identity Framework 将角色分配给 Postgres 数据库的用户错误 - CancellationTokenSource 已被释放
【发布时间】:2021-07-19 22:40:57
【问题描述】:

您好,我在使用 Identity Framework 5.0.5、.net5.0.5 和 Postgres SQL db 为用户分配角色时遇到问题。

用于将角色分配给用户的代码如下所示,错误如下。

如果可能,请提供帮助。

非常感谢!

       {
           if (!await roleManager.RoleExistsAsync("Admin"))
           {
               await roleManager.CreateAsync(new IdentityRole
               {
                   Name = "Admin"
               });
           }
           
           ApplicationUser user = await userManager.FindByIdAsync(userId);
           if (isAdmin)
           {
               await userManager.AddToRoleAsync(user, "Admin");
           }
           else
           {
               await userManager.RemoveFromRoleAsync(user, "Admin");
           }
       }
   }


services.AddDbContext<ApplicationDbContext>(options =>
   options.UseNpgsql(
       Configuration.GetConnectionString("DefaultConnection"), 
       builder => builder.EnableRetryOnFailure(50, TimeSpan.FromSeconds(5), null)));


System.ObjectDisposedException: The CancellationTokenSource has been disposed.
   at System.Threading.CancellationTokenSource.ThrowObjectDisposedException()
   at System.Threading.CancellationTokenSource.CancelAfter(Int32 millisecondsDelay)
   at System.Threading.CancellationTokenSource.CancelAfter(TimeSpan delay)
   at Npgsql.Util.ResettableCancellationTokenSource.Stop()
   at Npgsql.NpgsqlReadBuffer.<Ensure>g__EnsureLong|40_0(NpgsqlReadBuffer buffer, Int32 count, Boolean async, Boolean readingNotifications)
   at Npgsql.NpgsqlConnector.<ReadMessage>g__ReadMessageLong|194_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
   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(DbContext _, Boolean result, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func`4 operation, Func`4 verifySucceeded, TState state, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func`4 operation, Func`4 verifySucceeded, TState state, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
   at SearchDataScreening.Pages.UserManagement.OnGetAdminControl(String userId, Boolean isAdmin) in /Users/dewaldthattingh/GitHubRepos/TPS/SearchScreening/SearchDataScreening/Pages/UserManagement.cshtml.cs:line 50
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__140_1(Object state)
   at System.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(QueueUserWorkItemCallback quwi)
   at System.Threading.ExecutionContext.RunForThreadPoolUnsafe[TState](ExecutionContext executionContext, Action`1 callback, TState& state)
   at System.Threading.QueueUserWorkItemCallback.Execute()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

【问题讨论】:

  • 尝试设置一个断点并检查哪一行代码会抛出这个错误?此外,您可以尝试通过 DbContext 执行相同的操作,而不是使用 UserManager 和 RoleManager。

标签: c# .net postgresql asp.net-core asp.net-identity


【解决方案1】:

请尝试将其更改为不使用下面的等待方法

  bool roleExist =  roleManager.RoleExistsAsync("Admin").Result;
        if (!roleExist)
        {
            var x =  roleManager.CreateAsync(new IdentityRole
            {
                Name = "Admin"
            }).Result;
        }

        if (isAdmin)
        {
            var user =  userManager.FindByIdAsync(userId).Result;
            if (user != null)
            {
                var x = userManager.AddToRoleAsync(user, "Admin").Result;
            }
        }
        else
        {
            var user =  userManager.FindByIdAsync(userId).Result;
            if (user != null)
            {
                var x = userManager.RemoveFromRoleAsync(user, "Admin").Result;
            }
        }

【讨论】:

  • 你能解释一下为什么不用 await 关键字吗?
  • 我在玩这个,这是我似乎让它在我身边工作的唯一方法。使用 await 并没有让调用完成,并且项目尝试在前一个完成之前开始第二个操作,上述方式避免了它。我唯一能想到的原因是它与.net 5的某些问题有关。无论如何这对我有用:D
  • 你已经阻止了一个支持异步编程的方法,它似乎不是一个最佳实践
  • 我知道这一点,不幸的是,在这种情况下,最佳实践似乎无法正常工作。我只是给出我发现有效的解决方案
猜你喜欢
  • 1970-01-01
  • 2020-08-16
  • 2017-09-02
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多