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

本文关键字:NET ASP 角色 保存 用户 添加 MVC | 更新日期: 2023-09-27 17:55:25

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

我的帐户控制器中的用户角色方法:

[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();
    }

身份管理器类:

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() 行在最后。但是,我不知道为什么该模型无效。用户无处输入可能违反某种数据库或网页验证的值。每个角色旁边都有简单的复选框,用于指示要将用户分配到哪些角色。

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

帐户控制器中,您没有将更改保存到数据库中
使用 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();
}

希望对您有所帮助,请勾选正确的答案。 :)

我希望

这能帮助遇到这个问题并需要答案的人。您遇到的问题是您的 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);
            }
        }
 }

在 ClearUserRoles 函数中,您有 um.RemoveFromRole(userId, role.RoleId); .您提供角色 ID,其中应该是角色名称。

代码中实例化了 3 个 DbContext,看起来它们可能是嵌套的,这可能会有问题。尝试更改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);
    }
}