身份 2.1 - 从以前的所有角色中删除,然后添加到特定角色?加上这样做时调用 UserManager 时出错

Identity 2.1 - Remove from all previous roles, then add to specific role? Plus error in calling UserManager when doing so

我正在为系统管理员编写一个用户管理器,您可以在其中对用户对象执行各种功能。我目前的困境是我希望能够写出类似

的东西
await UserManager.RemoveFromRoleAsync(userID, any);

并将此人从之前的所有角色中删除。

现在我已经写了这段代码,但它 "feels" 很脏,可能会更好。我在测试时也遇到了一般性 "object not set to instance of an object" 错误。

控制器代码(userID和level是调用页面传入的):

var userID = "68790581-d2ae-4bc3-8db3-e4c8f4b0bb9f";
        string level = "FullAdmin";

//POST: /Account/MakeAdmin
        [HttpPost]
        [Authorize(Roles = "SuperAdmin")]
        public async Task<ActionResult> MakeAdmin(string userID, string level)
        {

        if(userID == null || level == null)
        {
            return View("Error");
        }

        if (level == "FullAdmin")
        {
            try
            {
                await UserManager.RemoveFromRoleAsync(userID, "Admin1");
            }

            catch { }

            try
            {
                await UserManager.RemoveFromRoleAsync(userID, "ReadOnly");
            }

            catch { }

            //Add to the desired role
            try
            {
                await UserManager.AddToRoleAsync(userID, "SuperAdmin");
            }
            catch (Exception ex)
            {
                ViewBag.Exception = ex;
            }



            return Content("Admin permissions activated");
        }

        if(level == "ReadOnlyAdmin")
        {
            try
            {
                await UserManager.RemoveFromRoleAsync(userID, "SuperAdmin");
            }

            catch { }

            try
            {
                await UserManager.RemoveFromRoleAsync(userID, "Admin1");
            }

            catch { }

    //Add to the desired role
            try
            {
                await UserManager.AddToRoleAsync(userID, "ReadOnly");
            }
            catch (Exception ex)
            {
                ViewBag.Exception = ex;
            }


            return Content("Read only admin permissions activated");
        }

        return View();
    }

此代码失败 - 这是我的堆栈跟踪:

 Test Name: PostMakeAdmin
Test FullName:  Testing.AccountTests.PostMakeAdmin
Test Source:    h:\app\Controllers\UnitTest1.cs : line 880
Test Outcome:   Failed
Test Duration:  0:00:00.5725984

Result Message: 
Test method Testing.AccountTests.PostMakeAdmin threw exception: 
System.NullReferenceException: Object reference not set to an instance of an object.
Result StackTrace:  
at System.Web.HttpContextBaseExtensions.GetOwinEnvironment(HttpContextBase context)
   at System.Web.HttpContextBaseExtensions.GetOwinContext(HttpContextBase context)
   at app.Controllers.AccountController.get_UserManager() in h:\app\Controllers\AccountController.cs:line 42
   at app.Controllers.AccountController.<MakeAdmin>d__c.MoveNext() in h:\app\Controllers\AccountController.cs:line 305
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at app.AccountTests.<PostMakeAdmin>d__d.MoveNext() in h:\app\Controllers\UnitTest1.cs:line 888
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()

感谢任何能提供帮助的人!

更新 初始迭代问题已解决。我收到有关 "Object reference not set to instance of an object" 与我的 UserManager 相关的错误。

这里是建立UserManager的代码:

 public AccountController()
    {
    }

    public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
    {
        UserManager = userManager;
        SignInManager = signInManager;
    }

    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

您可以获得用户所属的所有角色,迭代它们并删除。

   var user = await UserManager.FindByIdAsync(userId);
   await UserManager.RemoveFromRolesAsync(userId, UserManager.GetRoles(userId).ToArray());
   await UserManager.AddToRoleAsync(userId, "NewRole");
   await UserManager.UpdateAsync(user);

对于 Asp.Net Core 2.2.0,使用这个代替公认的答案

(GetRoles 不再存在,改用 GetRolesAsync)

await _userManager.RemoveFromRolesAsync(userObj, await _userManager.GetRolesAsync(userObj));
await _userManager.AddToRoleAsync(userObj, roleName);