ASP.NET Core 5 Razor Pages分配角色时视图传错Id到OnPost方法如何解决
问题分析
- 核心问题是下拉框模型绑定不匹配:你为
<select>设置的asp-for="RoleToAssign"绑定的是完整的IdentityRole类型对象,但下拉框提交的value只是角色ID字符串,ASP.NET Core模型绑定无法直接将字符串映射为IdentityRole实例,导致你获取到的RoleToAssign.Id取值异常,和你传入视图的ID不一致。 - 静态属性使用错误:你定义的
FirstID是static静态属性,该属性会在整个应用生命周期内共享,多用户并发访问时会出现值覆盖,干扰你的校验逻辑。 - 代码逻辑缺陷:
OnPost方法中RedirectToPage没有加return关键字,即使用户不存在也不会执行跳转;没有提前判断用户是否已经拥有目标角色,重复调用AddToRole会抛出异常。
解决方案
1. 调整PageModel绑定逻辑
删掉对完整IdentityRole对象的绑定,改为直接绑定角色ID和用户ID两个字符串属性,删除不需要的静态属性:
public class RoleManagerModel : PageModel { private readonly UserManager<ApplicationUser> _userManager; private readonly RoleManager<IdentityRole> _roleManager; public RoleManagerModel(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager) { _userManager = userManager; _roleManager = roleManager; } public IEnumerable<ApplicationUser> Users { get; set; } public IEnumerable<IdentityRole> Roles { get; set; } // 直接绑定提交的角色ID、用户ID,不需要绑定完整实体 [BindProperty] public string SelectedRoleId { get; set; } [BindProperty] public string UserId { get; set; } public async Task OnGet() { Users = await _userManager.Users.ToListAsync(); Roles = await _roleManager.Roles.ToListAsync(); } public async Task<IActionResult> OnPost() { var userToChangeRole = await _userManager.FindByIdAsync(UserId); if (userToChangeRole == null) // 补全return,否则跳转不生效 return RedirectToPage("/Identity/NotFound"); var roleToAssign = await _roleManager.FindByIdAsync(SelectedRoleId); if (roleToAssign == null) { ModelState.AddModelError(string.Empty, "所选角色不存在"); Users = await _userManager.Users.ToListAsync(); Roles = await _roleManager.Roles.ToListAsync(); return Page(); } // 先判断用户是否已经拥有该角色,避免重复添加报错 if (!await _userManager.IsInRoleAsync(userToChangeRole, roleToAssign.Name)) { await _userManager.AddToRoleAsync(userToChangeRole, roleToAssign.Name); } Users = await _userManager.Users.ToListAsync(); Roles = await _roleManager.Roles.ToListAsync(); return Page(); } }
2. 修改视图表单绑定
将下拉框的绑定对象改为SelectedRoleId,隐藏的用户ID也改为绑定UserId属性:
<td> <form method="post"> <div class="form-group"> <label>分配角色</label> <select class="form-control" asp-for="SelectedRoleId"> @foreach (var role in Model.Roles) { <option value="@role.Id">@role.Name</option> } </select> </div> <button type="submit" class="btn btn-primary btn-sm">Assign</button> <input type="hidden" asp-for="UserId" value="@user.Id" /> </form> </td>
内容的提问来源于stack exchange,提问作者upizs
相关产品推荐
相关产品推荐

