尝试将用户添加到ASP.NET MVC中的角色。更改未保存

时间:2014-03-31 04:31:48

标签: c# asp.net asp.net-mvc entity-framework roles

我正在处理的应用程序涉及能够将用户添加到各种角色。现在,我能够创建用户和角色,以及查看用户在种子数据中分配的角色。但是,当我尝试通过应用程序本身将用户添加到角色时,更改实际上不会保存回数据库。我没有收到任何类型的错误页面。以下是我认为相关的代码。

我的AccountController中的UserRole方法:

[Authorize(Roles = "Admin")]
    public ActionResult UserRoles(string id)
    {
        var Db = new ApplicationDbContext();
        var user = Db.Users.First(u => u.UserName == id);
        var model = new SelectUserRolesViewModel(user);
        return View(model);
    }

    [HttpPost]
    [Authorize(Roles = "Admin")]
    [ValidateAntiForgeryToken]
    public ActionResult UserRoles(SelectUserRolesViewModel model)
    {
        if (ModelState.IsValid)
        {
            var idManager = new IdentityManager();
            var Db = new ApplicationDbContext();
            var user = Db.Users.First(u => u.UserName == model.UserName);
            idManager.ClearUserRoles(user.Id);
            foreach (var role in model.Roles)
            {
                if (role.Selected)
                {
                    idManager.AddUserToRole(user.Id, role.RoleName);
                }
            }
            return RedirectToAction("IndexUser");
        }
        return View();
    }

Identity Manager类:

public class IdentityManager
{
    public bool AddUserToRole(string userId, string roleName)
    {
        var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
        var idResult = um.AddToRole(userId, roleName);
        return idResult.Succeeded;
    }

    public void ClearUserRoles(string userId)
    {
        var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
        var user = um.FindById(userId);
        var currentRoles = new List<IdentityUserRole>();
        currentRoles.AddRange(user.Roles);
        foreach (var role in currentRoles)
        {
            um.RemoveFromRole(userId, role.RoleId);
        }
    }
}

模型类:

public class SelectUserRolesViewModel
{
    // Enable initialization with an instance of ApplicationUser:
    public SelectUserRolesViewModel(ApplicationUser user)
        : this()
    {
        this.UserName = user.UserName;

        var Db = new ApplicationDbContext();

        // Add all available roles to the list of EditorViewModels:
        var allRoles = Db.Roles;
        foreach (var role in allRoles)
        {
            var rvm = new SelectRoleEditorViewModel(role);
            this.Roles.Add(rvm);
        }

        // Set the Selected property to true for those roles for 
        // which the current user is a member:
        foreach (var userRole in user.Roles)
        {
            var checkUserRole = this.Roles.Find(r => r.RoleID == userRole.RoleId);
            checkUserRole.Selected = true;
        }
    }

    public string UserName { get; set; }
    public List<SelectRoleEditorViewModel> Roles { get; set; }
}

// Used to display a single role with a checkbox, within a list structure:
public class SelectRoleEditorViewModel
{
    public SelectRoleEditorViewModel() { }

    public SelectRoleEditorViewModel(IdentityRole role)
    {
        this.RoleName = role.Name;
        this.RoleID = role.Id;
    }

    public bool Selected { get; set; }

    [Required]
    public string RoleName { get; set; }

    [Required]
    public string RoleID { get; set; }

}

现在我知道AddUserToRole方法可以正常工作,因为我在种子数据库时直接调用它并且它可以工作。有人有什么想法吗?

如需完整披露,此代码取自以下教程: http://www.codeproject.com/Articles/682113/Extending-Identity-Accounts-and-Implementing-Rol

修改 关于网页实际发生的更多描述。当我导航到页面以将角色分配给所选用户时,它会列出所有角色并预先检查用户已分配给的所有角色。我可以进行一些更改,然后单击“保存”按钮。但是,此时它返回相同的视图,但没有任何用户角色信息。然后,我可以再次单击“保存”,然后返回到用户列表页面。所以我猜想发生的事情是当第一次提交页面时,附加了模型值(用户和角色)模型状态总是无效,因此它绕过UserRoles方法中的所有代码并直接转向错误处理返回View()行的结尾。但是,我不知道为什么模型会无效。用户无处输入可能违反某种数据库或网页验证的值。每个角色旁边都有一个复选框,用于表示用户将分配给哪些角色。

4 个答案:

答案 0 :(得分:1)

帐户控制器中的

您没有将更改保存到数据库中 使用Db.SaveChanges();保存更改

[HttpPost]
[Authorize(Roles = "Admin")]
[ValidateAntiForgeryToken]
public ActionResult UserRoles(SelectUserRolesViewModel model)
{
    if (ModelState.IsValid)
    {
        var idManager = new IdentityManager();
        var Db = new ApplicationDbContext();
        var user = Db.Users.First(u => u.UserName == model.UserName);
        idManager.ClearUserRoles(user.Id);
        foreach (var role in model.Roles)
        {
            if (role.Selected)
            {
                idManager.AddUserToRole(user.Id, role.RoleName);
            }
        }
        Db.SaveChanges(); //for saving changes to the database 
        return RedirectToAction("IndexUser");
    }
    return View();
}

希望它对您有帮助,请勾选答案。 :)

答案 1 :(得分:1)

我希望这可以帮助遇到这个并需要答案的人。您遇到的问题是您的model.roles返回null,因此当您尝试添加新用户时,它应该会出错。但是,如果您检查它不是空的,那么它不会给出任何错误。此外,下次尝试自己添加错误消息时,如果无法执行操作,请使用try catch,您会收到错误消息。请尝试以下

if (model.Roles == null)
{
     model.Roles = new Role();
}
  else {
foreach (var role in model.Roles)
        {
            if (role.Selected)
            {
                idManager.AddUserToRole(user.Id, role.RoleName);
            }
        }
 }

答案 2 :(得分:0)

在代码中实例化了3个DbContexts,看起来它们可能是嵌套的,这可能会有问题。尝试更改IdentityManager以使用外部DbContext ...

public class IdentityManager
{
    private ApplicationDbContext context;

    public IdentityManager ()
    {
        context = new ApplicationDbContext(); // if none supplied
    }

    public IdentityManager (ApplicationDbContext applicationDbContext)
    {
        context = applicationDbContext;
    }

    public bool AddUserToRole(string userId, string roleName)
    {
        var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
        var idResult = um.AddToRole(userId, roleName);
        return idResult.Succeeded;
    }

    public void ClearUserRoles(string userId)
    {
        var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
        var user = um.FindById(userId);
        var currentRoles = new List<IdentityUserRole>();
        currentRoles.AddRange(user.Roles);
        foreach (var role in currentRoles)
        {
            um.RemoveFromRole(userId, role.RoleId);
        }
    }
}

并更改调用代码以传入DbContext ...

var Db = new ApplicationDbContext();
var idManager = new IdentityManager(Db);
var user = Db.Users.First(u => u.UserName == model.UserName);
idManager.ClearUserRoles(user.Id);
foreach (var role in model.Roles)
{
    if (role.Selected)
    {
        idManager.AddUserToRole(user.Id, role.RoleName);
    }
}

答案 3 :(得分:0)

在ClearUserRoles函数中,您有um.RemoveFromRole(userId, role.RoleId);。您将RoleId放在应该是RoleName的位置。