我试图复制Identity
脚手架页面(如Register.cshtml.cs
)中使用的cs代码,但要在Roles
和RoleManager
的上下文中使用。我只是想创建一个页面,创建一个"管理员";角色,并使用执行OnGet()
:
namespace Scratch.Pages
{
public class AdminUserModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly IUserStore<IdentityUser> _userStore;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly IRoleStore<IdentityRole> _roleStore;
private readonly ILogger<AdminUserModel> _logger;
public AdminUserModel(ILogger<AdminUserModel> logger,
UserManager<IdentityUser> userManager,
IUserStore<IdentityUser> userStore,
RoleManager<IdentityRole> roleManager,
IRoleStore<IdentityRole> roleStore)
{
_logger = logger;
_userManager = userManager;
_userStore = userStore;
_roleManager = roleManager;
_roleStore = roleStore;
}
public async void OnGet(bool setAdmin)
{
bool _setAdmin = setAdmin;
if (setAdmin)
{
await AdminUser();
}
RedirectToPage("/Index");
}
public async Task<IActionResult> AdminUser()
{
if (ModelState.IsValid)
{
IdentityRole adminRole;
bool roleExists = await _roleManager.RoleExistsAsync("Administrators");
if (!roleExists)
{
adminRole = CreateRole();
adminRole.Name = "Administrators";
adminRole.NormalizedName = "Administrators";
adminRole.ConcurrencyStamp = "x";
await _roleManager.CreateAsync(adminRole);
}
else
{
var _adminRole = await _roleManager.FindByNameAsync("Administrators");
adminRole = _adminRole;
}
if (User != null && User.Identity != null && User.Identity.IsAuthenticated)
{
var userName = User.Identity.Name;
IdentityUser user = await _userManager.FindByNameAsync(userName);
await _userManager.AddToRoleAsync(user, adminRole.Name);
}
TempData["success"] = "User added to admin role";
}
return Page();
}
private IdentityRole CreateRole()
{
try
{
return Activator.CreateInstance<IdentityRole>();
}
catch
{
throw new InvalidOperationException($"Can't create an instance of '{nameof(IdentityRole)}'. " +
$"Ensure that '{nameof(IdentityRole)}' is not an abstract class and has a parameterless constructor");
}
}
}
}
但是我在这(await _userManager.AddToRoleAsync(user, adminRole.Name);
)行遇到了这个错误。
System.ObjectDisposedException
HResult=0x80131622
Message=Cannot access a disposed object.
Object name: 'UserManager`1'.
Source=Microsoft.Extensions.Identity.Core
StackTrace:
at Microsoft.AspNetCore.Identity.UserManager`1.ThrowIfDisposed()
at Microsoft.AspNetCore.Identity.UserManager`1.<AddToRoleAsync>d__105.MoveNext()
at Scratch.Pages.AdminUserModel.<AdminUser>d__7.MoveNext() in C:UsersAlexDesktopPMPScratchScratchPagesAdminUser.cshtml.cs:line 90
at Scratch.Pages.AdminUserModel.<OnGet>d__6.MoveNext() in C:UsersAlexDesktopPMPScratchScratchPagesAdminUser.cshtml.cs:line 53
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_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.PortableThreadPool.WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()
如果我能越过bool roleExists = await _roleManager.RoleExistsAsync("Administrators");
行的错误,它显示:
System.Threading.Tasks.TaskCanceledException
HResult=0x8013153B
Message=A task was canceled.
Source=Microsoft.EntityFrameworkCore.Relational
StackTrace:
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.<OpenInternalAsync>d__70.MoveNext()
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.<OpenInternalAsync>d__70.MoveNext()
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.<OpenAsync>d__66.MoveNext()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.<ExecuteReaderAsync>d__19.MoveNext()
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.<InitializeReaderAsync>d__19.MoveNext()
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.<ExecuteAsync>d__7`2.MoveNext()
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.<MoveNextAsync>d__18.MoveNext()
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.<SingleOrDefaultAsync>d__15`1.MoveNext()
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.<SingleOrDefaultAsync>d__15`1.MoveNext()
at Microsoft.AspNetCore.Identity.RoleManager`1.<RoleExistsAsync>d__33.MoveNext()
at Scratch.Pages.AdminUserModel.<AdminUser>d__7.MoveNext() in C:UsersAlexDesktopPMPScratchScratchPagesAdminUser.cshtml.cs:line 68
at Scratch.Pages.AdminUserModel.<OnGet>d__6.MoveNext() in C:UsersAlexDesktopPMPScratchScratchPagesAdminUser.cshtml.cs:line 53
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_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.PortableThreadPool.WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()
70%的时间
所以要么我遗漏了什么要么我做错了。请帮助。
我只需要使用public async Task OnGetAsync()
而不是public async void OnGet()
。我没有意识到Task
的操作就像一个函数修饰符(尽管它是一个类,这有点令人困惑),使函数异步。