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

Asp.Net Core 6调用删除模态框确认动作时出现405错误

Asp.Net Core通用删除模态框405错误解决方法

问题描述

我正在开发首个Asp.Net Core应用,对模态框、Razor页面和路由映射完全陌生,JavaScript也已生疏。尝试制作一个可用于任意对象(测试对象为Employee类型)的通用删除模态框,模态框能正常显示,但点击调用DeletePOST方法时出现405错误,请求URL为https://localhost:44313/Employee/DeletePOST/1(选中ID为1的员工时),控制台出现警告:(index):6789 crbug/1173575, non-JS module files deprecated.(anonymous) @ (index):6789。


问题分析

405 Method Not Allowed错误的直接原因是:通过window.location.href = pathToDelete发起的是GET请求,但后端DeletePOST方法标记了[HttpPost]属性,仅接受POST请求,因此服务器拒绝该请求。

另外还有两处细节问题:

  • 视图中循环生成的删除按钮都使用了相同的id="#delete",违反HTML中id必须唯一的规则
  • JavaScript中获取data-id时,若点击的是按钮内的<i>图标,e.target会指向图标元素而非按钮,导致无法正确获取data-id

解决方案

1. 修正视图代码(View.Employee.Index)

删除重复的id="#delete",并修正data-url的生成方式:

<tbody>
    @foreach (var employee in Model)
    {
        <tr id="row_@employee.Id">
            <td>@employee.Name</td>
            <td>@employee.Phone</td>
            <td>@employee.Email</td>
            <td>@employee.Address</td>
            <td>@employee.Role</td>
            <td>@employee.Availability</td>
                    
            <td class="w-100 btn-group" role="group">
                <a asp-controller="Employee" asp-action="Edit" asp-route-id="@employee.Id"
                   class="btn btn-primary mx-2"> <i class="bi bi-pencil-square"></i> Edit</a>
                        
                <!--delete modal confirmation button-->
                <a class="btn btn-danger delete" data-id="@employee.Id" 
                   data-url="@Url.Action("DeletePOST", "Employee")"
                   data-body-message="Are you sure you want to delete this employee?">
                   <i class="bi bi-trash"></i> Delete</a>
            </td>
                    
        </tr>
    }
</tbody>

2. 修改JavaScript提交逻辑(wwwroot.js.delete.js)

替换window.location.href的跳转方式,改为动态创建表单提交POST请求,同时包含防伪令牌:

$((function () {
    var pathToDelete;
    var id;

    $('body').append(`
                    <div class="modal fade" id="deleteModal" tabindex="-1" role="dialog"
                         aria-labelledby="myModalLabel">
                        <div class="modal-dialog" role="document">
                            <div class="modal-content">
                                <div class="modal-header">
                                    <button type="button" class="close" data-bs-dismiss="modal" 
                                      aria-label="Close"><span aria-hidden="true">&times;</span> </button>
                                    <h4 class="modal-title" id="myModalLabel">Warning</h4>
                                </div>
                                <div class="modal-body delete-modal-body">
                                </div>
                                <div class="modal-footer">
                                    <button type="button" class="btn btn-default" data-dismiss="modal" 
                                        id="cancel-delete">Cancel</button>
                                    <button type="button" class="btn btn-danger" 
                                        id="confirm-delete">Delete</button>
                                </div>
                            </div>
                        </div>
                    </div>`);
    
    //Delete Action
    $(".delete").on('click', (e) => {
        e.preventDefault();
        // 用currentTarget确保获取的是按钮本身,而非内部图标
        const $btn = $(e.currentTarget);
        id = $btn.data('id');
        pathToDelete = $btn.data('url');
        
        var bodyMessage = $btn.data('body-message');
        // 拼接id到请求路径
        pathToDelete = `${pathToDelete}/${id}`;
        $(".delete-modal-body").text(bodyMessage);
        $("#deleteModal").modal('show');
    });

    $("#confirm-delete").on('click', () => {
        // 动态创建表单提交POST请求
        const form = $('<form>', {
            method: 'POST',
            action: pathToDelete
        });
        // 添加防伪令牌(Asp.Net Core默认需要)
        form.append($('<input>', {
            type: 'hidden',
            name: '__RequestVerificationToken',
            value: $('input[name="__RequestVerificationToken"]').val()
        }));
        // 提交表单
        form.appendTo('body').submit();
        // 关闭模态框
        $("#deleteModal").modal('hide');
    });
}()));

3. 控制器代码(可选优化)

如果希望更符合REST规范,可以将方法改为接受DELETE请求,同时兼容POST:

[HttpPost, HttpDelete]
[ValidateAntiForgeryToken]
public IActionResult DeletePOST(int? id)
{
    var selectedEmployee = _db.Employees.Find(id);
    if (selectedEmployee == null)
    {
        return NotFound();
    }
    _db.Employees.Remove(selectedEmployee);
    _db.SaveChanges();
    return RedirectToAction("Index");
}

如果改用DELETE请求,JavaScript中需要修改表单的method为DELETE,Asp.Net Core默认已支持HTTP DELETE方法,防伪令牌仍需包含。


关于控制台警告

crbug/1173575, non-JS module files deprecated是Chrome浏览器的警告,和删除功能无关,是浏览器对非JS模块文件加载方式的提示,无需处理。

内容的提问来源于stack exchange,提问作者user17195990

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:05:28