涉及到的 Model 和 ViewModel:
namespace StudentManagement.Models{public class UserClaim{public string ClaimType { get; set; }public bool IsSelected { get; set; }}}namespace StudentManagement.ViewModels{public class UserClaimsViewModel{public string UserId { get; set; }public List<UserClaim> Claims { get; set; }public UserClaimsViewModel(){Claims = new List<UserClaim>();}}}
为了方便调试,先制作一个内存中的 Claim 集合:
namespace StudentManagement.Models{public class ClaimsStore{public static List<Claim> AllClaims = new List<Claim>{new Claim("Create Role","Create Role"),new Claim("Edit Role","Edit Role"),new Claim("Delete Role","Delete Role"),new Claim("Edit Student","Edit Student")};}}
编辑用户声明的方法:
[HttpGet]public async Task<IActionResult> ManageUserClaims(string userId){var user = await _userManager.FindByIdAsync(userId);if (user == null){ViewBag.ErrorMessage = $"无法找到 Id {userId} 的用户";return View("NotFound");}// 获取用户当前所有 Claimvar existingUserClaims = await _userManager.GetClaimsAsync(user);var model = new UserClaimsViewModel{UserId = userId};foreach (var claim in ClaimsStore.AllClaims){var userClaim = new UserClaim{ClaimType = claim.Type};if (existingUserClaims.Any(c => c.Type == claim.Type)){userClaim.IsSelected = true;}model.Claims.Add(userClaim);}return View(model);}[HttpPost]public async Task<IActionResult> ManageUserClaims(UserClaimsViewModel model){var user = await _userManager.FindByIdAsync(model.UserId);if (user == null){ViewBag.ErrorMessage = $"无法找到 Id {model.UserId} 的用户";return View("NotFound");}var claims = await _userManager.GetClaimsAsync(user);var removeClaimsResult = await _userManager.RemoveClaimsAsync(user, claims);if (!removeClaimsResult.Succeeded){ModelState.AddModelError("", "无法删除当前用户的声明");return View(model);}var addClaimsResult = await _userManager.AddClaimsAsync(user,model.Claims.Where(c => c.IsSelected).Select(c => new Claim(c.ClaimType, c.ClaimType)));if (!addClaimsResult.Succeeded){ModelState.AddModelError("", "无法向用户添加选定的声明");return View(model);}return RedirectToAction("EditUser", new { Id = model.UserId });}
管理用户声明的视图(和管理用户角色的视图很相似):
@model UserClaimsViewModel<form method="post"><div class="card"><div class="card-header"><h2>管理用户声明</h2></div><div class="card-body">@for (var i = 0; i < Model.Claims.Count; i++){<div class="form-check m-1"><input type="hidden" asp-for="@Model.Claims[i].ClaimType" /><input asp-for="@Model.Claims[i].IsSelected" class="form-check-input" /><label class="form-check-label" asp-for="@Model.Claims[i].IsSelected">@Model.Claims[i].ClaimType</label></div>}<div asp-validation-summary="All" class="text-danger"></div></div><div class="card-footer"><input type="submit" value="更新" class="btn btn-primary" style="width: auto" /><a class="btn btn-primary" style="width: auto" asp-action="EditUser" asp-route-id="@Model.UserId">取消</a></div></div></form>
