Asp.net mvc 标识2.1-从以前的所有角色中删除,然后添加到特定角色?执行此操作时调用UserManager时出错

Asp.net mvc 标识2.1-从以前的所有角色中删除,然后添加到特定角色?执行此操作时调用UserManager时出错,asp.net-mvc,asp.net-identity,Asp.net Mvc,Asp.net Identity,我正在为系统管理员编写一个用户管理器,您可以在其中对用户对象执行各种功能。我目前的困境是,我希望能够写出这样的东西 await UserManager.RemoveFromRoleAsync(userID, any); 并将该人员从之前的所有角色中移除 现在我已经写了这段代码,但它“感觉”脏,可能会更好。在测试时,我还遇到了一个通用的“对象未设置为对象实例”错误 控制器代码(从调用页传入用户ID和级别): var userID=“68790581-d2ae-4bc3-8db3-e4c8f4b0

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

await UserManager.RemoveFromRoleAsync(userID, any);
并将该人员从之前的所有角色中移除

现在我已经写了这段代码,但它“感觉”脏,可能会更好。在测试时,我还遇到了一个通用的“对象未设置为对象实例”错误

控制器代码(从调用页传入用户ID和级别):

var userID=“68790581-d2ae-4bc3-8db3-e4c8f4b0bb9f”;
string level=“FullAdmin”;
//POST:/Account/MakeAdmin
[HttpPost]
[授权(角色=“超级管理员”)]
公共异步任务MakeAdmin(字符串用户ID,字符串级别)
{
if(userID==null | | level==null)
{
返回视图(“错误”);
}
如果(级别==“FullAdmin”)
{
尝试
{
等待UserManager.RemoveFromRoleAsync(userID,“Admin1”);
}
捕获{}
尝试
{
等待UserManager.RemoveFromRoleAsync(userID,“ReadOnly”);
}
捕获{}
//添加到所需的角色
尝试
{
wait UserManager.AddToRoleAsync(userID,“SuperAdmin”);
}
捕获(例外情况除外)
{
ViewBag.Exception=ex;
}
返回内容(“已激活管理员权限”);
}
如果(级别=“ReadOnlyAdmin”)
{
尝试
{
等待UserManager.RemoveFromRoleAsync(userID,“SuperAdmin”);
}
捕获{}
尝试
{
等待UserManager.RemoveFromRoleAsync(userID,“Admin1”);
}
捕获{}
//添加到所需的角色
尝试
{
wait UserManager.AddToRoleAsync(userID,“ReadOnly”);
}
捕获(例外情况除外)
{
ViewBag.Exception=ex;
}
返回内容(“只读管理员权限已激活”);
}
返回视图();
}
此代码失败-以下是我的堆栈跟踪:

 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()
测试名称:PostMakeAdmin
测试全名:Testing.AccountTests.PostMakeAdmin
测试源:h:\app\Controllers\UnitTest1.cs:第880行
测试结果:失败
测试持续时间:0:00:00.5725984
结果消息:
测试方法Testing.AccountTests.PostMakeAdmin引发异常:
System.NullReferenceException:对象引用未设置为对象的实例。
结果跟踪:
位于System.Web.HttpContextBaseExtensions.GetowinenEnvironment(HttpContextBase上下文)
位于System.Web.HttpContextBaseExtensions.GetOwinContext(HttpContextBase上下文)
在h:\app\Controllers\AccountController.cs中的app.Controllers.AccountController.get\u UserManager()处:第42行
在h:\app\Controllers\AccountController.cs中的app.Controllers.AccountController.d\u c.MoveNext()处:第305行
---来自引发异常的上一个位置的堆栈结束跟踪---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中
在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()中
在h:\app\Controllers\UnitTest1.cs中的app.AccountTests.d\uu d.MoveNext()处:第888行
---来自引发异常的上一个位置的堆栈结束跟踪---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中
在System.Runtime.CompilerServices.TaskAwaiter.GetResult()中
感谢所有能帮忙的人

更新 解决了初始迭代问题。我的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;
        }
    }
publiccountcontroller()
{
}
公共帐户控制器(ApplicationUserManager用户管理器、ApplicationSignInManager signInManager)
{
UserManager=UserManager;
SignInManager=SignInManager;
}
公共应用程序管理员用户管理器
{
得到
{
返回_userManager??HttpContext.GetOwinContext().GetUserManager();
}
专用设备
{
_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.NETCore2.2.0,请使用此选项,而不是公认的答案 (GetRoles不再存在,请改用GetRolesAsync)


您在
await UserManager.RemoveFromRoleAsync(userID,只读)处出现语法错误
。在只读之前打开你的报价。这将使其更具可读性。漂亮的代码-肯定集成了它,但问题仍然存在。我仍然收到UserManager的异常错误。在单元测试时出错?你需要模拟一些依赖项。你的代码没问题,问题在于你的单元测试。有一些依赖项是正常的当应用程序运行时会被注入,但当从单元测试运行时,它将失败,因为这些依赖项不可用。你必须模拟这些依赖项,检查我在此之前粘贴在评论中的链接。明白。我将模拟我需要的详细信息。非常感谢你的帮助!
   var user = await UserManager.FindByIdAsync(userId);
   await UserManager.RemoveFromRolesAsync(userId, UserManager.GetRoles(userId).ToArray());
   await UserManager.AddToRoleAsync(userId, "NewRole");
   await UserManager.UpdateAsync(user);
await _userManager.RemoveFromRolesAsync(userObj, await _userManager.GetRolesAsync(userObj));
await _userManager.AddToRoleAsync(userObj, roleName);