To authorize users, it isn’t enough to just create and delete roles; I also have to be able to manage role memberships, assigning and removing users from the roles that the application defines. This isn’t a complicated process, but it invokes taking the role data from the AppRoleManager class and then calling the methods defined by the AppUserMangager class that associate users with roles.
为了授权用户,仅仅创建和删除角色还不够。还必须能够管理角色成员,从应用程序定义的角色中指定和除去用户。这不是一个复杂的过程,但它要从AppRoleManager类获取角色数据,然后调用将用户与角色关联在一起的AppUserMangager类所定义的方法。
I started by defining view models that will let me represent the membership of a role and receive a new set of membership instructions from the user. Listing 14-13 shows the additions I made to the UserViewModels.cs file.
我首先定义了视图模型,这让我能够表示一个角色中的成员,并能够从用户那里接收一组新成员的指令。清单14-13显示了在UserViewModels.cs文件中所做的添加。
Listing 14-13. Adding View Models to the UserViewModels.cs File
清单14-13. 添加到UserViewModels.cs文件的视图模型
namespace Users.Models {
public class CreateModel { [Required] public string Name { get; set; } [Required] public string Email { get; set; } [Required] public string Password { get; set; } }
public class LoginModel { [Required] public string Name { get; set; } [Required] public string Password { get; set; } }
public class RoleEditModel { public AppRole Role { get; set; } public IEnumerable<AppUser> Members { get; set; } public IEnumerable<AppUser> NonMembers { get; set; } }
public class RoleModificationModel { [Required] public string RoleName { get; set; } public string[] IdsToAdd { get; set; } public string[] IdsToDelete { get; set; } } }
The RoleEditModel class will let me pass details of a role and details of the users in the system, categorized by membership. I use AppUser objects in the view model so that I can extract the name and ID for each user in the view that will allow memberships to be edited. The RoleModificationModel class is the one that I will receive from the model binding system when the user submits their changes. It contains arrays of user IDs rather than AppUser objects, which is what I need to change role memberships.
RoleEditModel类使我能够在系统中传递角色细节和用户细节,按成员进行归类。我在视图模型中使用了AppUser对象,以使我在编辑成员的视图中能够为每个用户提取用户名和ID。RoleModificationModel类是在用户递交他们的修改时,从模型绑定系统接收到的一个类。它含有用户ID的数组,而不是AppUser对象,这是对角色成员进行修改所需要的。
Having defined the view models, I can add the action methods to the controller that will allow role memberships to be defined. Listing 14-14 shows the changes I made to the RoleAdmin controller.
定义了视图模型之后,便可以在控制器中添加动作方法,以便定义角色成员。清单14-14显示了我对RoleAdmin控制器所做的修改。
Listing 14-14. Adding Action Methods in the RoleAdminController.cs File
清单14-14. 在RoleAdminController.cs文件中添加动作方法
namespace Users.Controllers { public class RoleAdminController : Controller {
// ...other action methods omitted for brevity... // ...出于简化,这里忽略了其他动作方法 ...
public async Task<ActionResult> Edit(string id) { AppRole role = await RoleManager.FindByIdAsync(id); string[] memberIDs = role.Users.Select(x => x.UserId).ToArray(); IEnumerable<AppUser> members = UserManager.Users.Where(x => memberIDs.Any(y => y == x.Id)); IEnumerable<AppUser> nonMembers = UserManager.Users.Except(members); return View(new RoleEditModel { Role = role, Members = members, NonMembers = nonMembers }); }
[HttpPost] public async Task<ActionResult> Edit(RoleModificationModel model) { IdentityResult result; if (ModelState.IsValid) { foreach (string userId in model.IdsToAdd ?? new string[] { }) { result = await UserManager.AddToRoleAsync(userId, model.RoleName); if (!result.Succeeded) { return View("Error", result.Errors); } } foreach (string userId in model.IdsToDelete ?? new string[] { }) { result = await UserManager.RemoveFromRoleAsync(userId, model.RoleName); if (!result.Succeeded) { return View("Error", result.Errors); } } return RedirectToAction("Index"); } return View("Error", new string[] { "Role Not Found" }); }
private void AddErrorsFromResult(IdentityResult result) { foreach (string error in result.Errors) { ModelState.AddModelError("", error); } }
private AppUserManager UserManager { get { return HttpContext.GetOwinContext().GetUserManager<AppUserManager>(); } }
private AppRoleManager RoleManager { get { return HttpContext.GetOwinContext().GetUserManager<AppRoleManager>(); } } } }