涉及到的 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");
}
// 获取用户当前所有 Claim
var 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>