You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:53:32