使用asp.net身份更新用户角色



我有以下问题。当使用下面的代码更改用户的当前角色时,我得到一个异常,消息如下:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public virtual ActionResult Edit(User user, string role)
    {
        if (ModelState.IsValid)
        {
            var oldUser = DB.Users.SingleOrDefault(u => u.Id == user.Id);
            var oldRoleId = oldUser.Roles.SingleOrDefault().RoleId;
            var oldRoleName = DB.Roles.SingleOrDefault(r => r.Id == oldRoleId).Name;
            if (oldRoleName != role)
            {
                Manager.RemoveFromRole(user.Id, oldRoleName);
                Manager.AddToRole(user.Id, role);
            }
            DB.Entry(user).State = EntityState.Modified;
            return RedirectToAction(MVC.User.Index());
        }
        return View(user);
    }

附加一个model . entities类型的实体。用户失败,因为另一个相同类型的实体已经具有相同的主键值。当使用"Attach"方法或将实体的状态设置为"Unchanged"或"Modified"(如果图中的任何实体具有冲突的键值)时,可能会发生这种情况。这可能是因为一些实体是新的,还没有接收到数据库生成的键值。在这种情况下,使用"添加"方法或"添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"修改"。

有谁知道解决这个问题的好办法吗?

问题是您的Manager和DB不使用相同的DbContext。因此,当您将用户从DB的上下文发送到Manager时,它将把它作为"新"用户处理—然后您就不能从角色中删除它。这里有两条路可走。最简单的方法是从你的经理那里获得用户。

[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult Edit(User user, string role)
{
    if (ModelState.IsValid)
    {
        // THIS LINE IS IMPORTANT
        var oldUser = Manager.FindById(user.Id);
        var oldRoleId = oldUser.Roles.SingleOrDefault().RoleId;
        var oldRoleName = DB.Roles.SingleOrDefault(r => r.Id == oldRoleId).Name;
        if (oldRoleName != role)
        {
            Manager.RemoveFromRole(user.Id, oldRoleName);
            Manager.AddToRole(user.Id, role);
        }
        DB.Entry(user).State = EntityState.Modified;
        return RedirectToAction(MVC.User.Index());
    }
    return View(user);
}

更优雅的方法是开始使用像AutoFac (https://code.google.com/p/autofac/wiki/MvcIntegration)这样的di框架,并将DbContext设置为InstancePerApiRequest。

builder.RegisterType<YourDbContext>().As<DbContext>().InstancePerApiRequest();

我的角色是在我的DbMigrationsConfiguration类的种子方法中管理的,我像这样重命名它:

        if (context.Roles.Any(r => r.Name == "User"))
        {
            var store = new RoleStore<IdentityRole>(context);
            var manager = new RoleManager<IdentityRole>(store);
            var role = manager.Roles.First(r => r.Name == "User");
            role.Name = "NewNameForUser";
            manager.Update(role);
        }

In Identity Version 6.0.8这是我的工作。

if (role != currentrole)
            {
                _context.UserRoles.Remove(userIdData);
                _context.SaveChanges();
                userIdData.RoleId = aspnetroleId.Single();
                userIdData.UserId = userId;
                _context.UserRoles.Add(userIdData);
                _context.SaveChanges();         
                                    
            }

相关内容

  • 没有找到相关文章

最新更新