如何在Asp.Net Core中通过Ajax实现数据库删除操作?
Error: undefined的问题及控制器返回优化方案 让我们一步步拆解你遇到的问题,先从最直接的Ajax错误说起:
一、Ajax请求的核心错误(导致Error: undefined的直接原因)
你的Ajax代码里有两个关键问题,直接导致请求失败或者后端无法正确接收参数:
错误的选择器,无法获取正确的ProductId
你写的$('DeleteItem#data-id').val()完全是错误的选择器语法——DeleteItem不是标签名,#data-id是id选择器,但你的按钮并没有这个id,而是用data-id属性存ProductId。正确的做法是获取当前点击的按钮的data-id值,因为每个删除按钮都绑定了这个属性:data: { id: $(this).data('id') },未阻止按钮的默认表单提交行为
你的删除按钮在<form>标签内,点击按钮时会默认触发表单的提交事件,这会中断你的Ajax请求,导致请求异常终止,进而触发error回调。必须在点击事件开头加上:e.preventDefault();Error回调参数使用错误
jQuery的Ajax error回调参数是xhr, status, error,不是你以为的返回数据对象,所以直接访问data.id自然会得到undefined。你应该修改回调来获取准确的错误信息:error: function (xhr, status, error) { alert("Error: " + error); }
修正后的完整Ajax代码:
$('[name="DeleteItem"]').click(function (e) { e.preventDefault(); // 阻止默认表单提交 $.ajax({ type: "DELETE", url: "@Url.Action('Delete','Home')", data: { id: $(this).data('id') }, // 获取当前按钮的ProductId success: function () { alert("success!"); window.location.replace("@Url.Action('Index', 'Home')"); }, error: function (xhr, status, error) { alert("Error: " + error); } }); });
二、控制器端的问题(参数不匹配+返回值错误)
你的控制器代码也有几个关键问题:
参数名不匹配,无法接收前端传来的ProductId
前端Ajax发送的参数是id,但控制器方法的参数是[Bind("ShoppingCartItemProductId")] ViewModelAddToCart model,这导致后端无法正确绑定参数,model.ShoppingCartItemProductId会是默认值(比如0),进而导致后续查询失败,ModelState可能无效。最简单的修正方式是直接接收
int id参数:[HttpDelete] [ValidateAntiForgeryToken] // 后续会说明必要性 public async Task<IActionResult> Delete(int id) // 直接接收id参数 { // 后续逻辑用id代替model.ShoppingCartItemProductId }HttpDelete方法返回RedirectToAction是错误的
因为这是Ajax请求,浏览器不会自动执行重定向——RedirectToAction返回的是302状态码,Ajax会接收这个响应,但不会跳转到新页面。正确的做法是返回JSON结果或者状态码,让前端的success回调来处理页面跳转:if (ModelState.IsValid) { // ... 你的删除逻辑 ... await _context.SaveChangesAsync(); return Json(new { success = true }); // 返回成功的JSON // 或者如果不需要额外数据,直接返回200状态码:return Ok(); } else { return BadRequest(ModelState); // 返回错误状态码和错误信息 }Session初始化的问题
HttpContext.Session.SetString("_Name", "MyStore");不应该写在Delete方法里,Session的配置应该在Program.cs/Startup.cs中完成(添加Session中间件),否则可能导致SessionId不稳定。删除逻辑的健壮性优化
如果cartInfo或者cartItemInfo不存在,你的代码仍然会执行SaveChangesAsync(),这可能导致无意义的数据库操作。建议在这些判断里直接返回错误:if (cartInfo == null) { return BadRequest("购物车不存在"); } // ... if (cartItemInfo == null) { return BadRequest("购物车商品不存在"); }
三、关于[ValidateAntiForgeryToken]的必要性
需要添加。ASP.NET Core中,所有修改服务器状态的请求(POST/PUT/DELETE)都应该验证防伪令牌,防止CSRF攻击。要让Ajax请求支持防伪令牌,你需要:
在页面里添加防伪令牌的元标签(通常在_Layout.cshtml里):
@Html.AntiForgeryToken()在Ajax请求里添加请求头,带上令牌:
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
这样控制器上的[ValidateAntiForgeryToken]就能正常验证了。
总结
- 修正Ajax的选择器、默认行为阻止,优化error回调的错误信息获取;
- 修正控制器的参数绑定,将返回值改为JSON或状态码;
- 添加防伪令牌验证,确保请求安全;
- 优化控制器内的删除逻辑,增强健壮性。
内容的提问来源于stack exchange,提问作者Stian

