.NET Core MVC中使用Ajax删除Identity Framework角色失败求助
角色删除失败的排查与解决
1. 缺失AntiForgeryToken导致请求被拦截
动态生成的表单未包含ASP.NET Core要求的防跨站请求伪造令牌,而控制器方法添加了[ValidateAntiForgeryToken]特性,提交时会直接被拒绝。
解决方法:
在动态表单中插入防伪造令牌。若页面支持Razor语法,直接添加:
{ "data": "id", "render": function (data) { return ` <form asp-action="Delete" asp-route-id="${data}" method="post"> @Html.AntiForgeryToken() <button type="submit" class="btn btn-danger btn-small" onclick="return confirm('Are you sure you want to delete this?')"> <i class="fas fa-trash mr-1"></i> DELETE </button> </form> ` } }
若为纯前端JS环境,先在页面头部渲染令牌,再动态插入:
<!-- 页面头部预先渲染令牌 --> @Html.AntiForgeryToken()
{ "data": "id", "render": function (data) { const token = document.querySelector('input[name="__RequestVerificationToken"]').value; return ` <form asp-action="Delete" asp-route-id="${data}" method="post"> <input type="hidden" name="__RequestVerificationToken" value="${token}" /> <button type="submit" class="btn btn-danger btn-small" onclick="return confirm('Are you sure you want to delete this?')"> <i class="fas fa-trash mr-1"></i> DELETE </button> </form> ` } }
2. 直接从DbContext获取角色实例导致DeleteAsync失败
用_db.Roles.FirstOrDefault获取的角色实例未被RoleManager上下文跟踪,调用DeleteAsync时可能无法正确执行。
解决方法:
改用RoleManager的方法获取角色,并捕获删除操作的结果:
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Delete(string id) { var objFromDb = await _roleManager.FindByIdAsync(id); if (objFromDb == null) { TempData[SD.Error] = "Role not found."; return RedirectToAction(nameof(Roles)); } var userRolesCount = _db.UserRoles.Count(u => u.RoleId == id); if(userRolesCount > 0) { TempData[SD.Error] = "Cannot delete this role, since there are users assigned to it."; return RedirectToAction(nameof(Roles)); } var deleteResult = await _roleManager.DeleteAsync(objFromDb); if (deleteResult.Succeeded) { TempData[SD.Success] = "Role deleted successfully."; } else { TempData[SD.Error] = string.Join(", ", deleteResult.Errors.Select(e => e.Description)); } return RedirectToAction(nameof(Roles)); }
3. 检查DbContext实例一致性
确保_db(自定义DbContext)和_roleManager使用同一个DbContext实例。若依赖注入配置错误,两个服务实例分离会导致跟踪冲突,无法提交删除更改。
解决方法:
确认Program.cs(或Startup.cs)中DbContext配置为Scoped生命周期:
// Program.cs示例 builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddRoles<IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>();
4. 验证TempData提示是否正确显示
可能删除操作已执行,但前端未正确读取TempData信息,导致误以为删除失败。
解决方法:
在Roles视图中添加TempData显示逻辑:
@if (TempData[SD.Error] != null) { <div class="alert alert-danger">@TempData[SD.Error]</div> } @if (TempData[SD.Success] != null) { <div class="alert alert-success">@TempData[SD.Success]</div> }
5. 捕获未处理的异常
添加异常捕获逻辑,查看具体错误原因:
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Delete(string id) { try { // 原有业务代码 } catch (Exception ex) { TempData[SD.Error] = $"Delete failed: {ex.Message}"; return RedirectToAction(nameof(Roles)); } }
内容的提问来源于stack exchange,提问作者Mohamad Usman
相关产品推荐
相关产品推荐

