ASP.NET MVC中SQL Server数据删除404错误排查与解决
ASP.NET MVC删除预订时404错误及删除流程修复方案
问题背景
开发ASP.NET MVC应用时,涉及AvailableDates和Bookings两张SQL Server数据表。用户在UI选择日期删除预订时,需删除Bookings表中对应(包含所选日期、提交日期、用户名)的行。已实现“确认取消预订”按钮,但点击后触发404错误:无法找到网页https://localhost:44355/Booking/ConfirmCancelBooking。需解决该404错误,并确保ConfirmCancelBooking动作正确处理删除流程。
模型代码
public class AvailableDate { public int Id { get; set; } public DateTime Date { get; set; } } public class Booking { public int Id { get; set; } public string Username { get; set; } public DateTime SelectedDate { get; set; } public DateTime SubmissionDate { get; set; } }
控制器代码
public class BookingController : Controller { private readonly MyDbContext _context; public BookingController(MyDbContext context) { _context = context; } public IActionResult CancelBooking(int bookingId) { string fullUsername = User.Identity.Name; var booking = _context.Bookings.SingleOrDefault(b => b.Id == bookingId && b.Username == fullUsername); if (booking == null) { return NotFound(); } return View(booking); } [HttpPost] public IActionResult ConfirmCancelBooking(int bookingId) { string fullUsername = User.Identity.Name; var booking = _context.Bookings.SingleOrDefault(b => b.Id == bookingId && b.Username == fullUsername); if (booking == null) { return NotFound(); } _context.Bookings.Remove(booking); _context.SaveChanges(); return RedirectToAction("Index"); } }
视图代码
@{ ViewBag.Title = "Cancel Booking"; } <h2>Cancel Booking</h2> <p>Are you sure you want to cancel your booking for @Model.SelectedDate?</p> @using (Html.BeginForm("ConfirmCancelBooking", "Booking", FormMethod.Post)) { @Html.HiddenFor(model => model.Id) <input type="submit" value="Confirm Cancellation" class="btn btn-danger" /> <a href="@Url.Action("Index", "Booking")" class="btn btn-secondary">Back to Bookings</a> }
一、修复404错误
1. 修正参数名称不匹配问题
视图通过@Html.HiddenFor(model => model.Id)传递的参数是Id,但控制器ConfirmCancelBooking方法接收的参数名是bookingId,参数名不匹配导致路由无法找到对应动作。
两种修复方式:
- 方式一:修改控制器方法参数名,与视图传递的参数名一致
[HttpPost] public IActionResult ConfirmCancelBooking(int id) // 将bookingId改为id { string fullUsername = User.Identity.Name; var booking = _context.Bookings.SingleOrDefault(b => b.Id == id && b.Username == fullUsername); // 其余逻辑不变 }
- 方式二:修改视图隐藏字段,指定参数名为
bookingId
@Html.Hidden("bookingId", Model.Id)
2. 检查路由配置
确认项目路由配置正确启用控制器路由(以ASP.NET Core 6+为例,在Program.cs中):
app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
若控制器在自定义命名空间下,需在路由中指定命名空间:
app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}", namespaces: new[] { "YourApp.Controllers" });
3. 验证控制器命名规范
确保控制器类名为BookingController(必须以Controller为后缀),且所在命名空间被项目扫描覆盖。
二、确保删除流程正确
1. 优化数据查询逻辑
用FirstOrDefault替代SingleOrDefault,避免因数据库存在重复记录时抛出异常:
var booking = _context.Bookings.FirstOrDefault(b => b.Id == id && b.Username == fullUsername);
2. 添加异常处理与用户反馈
在删除操作中捕获数据库异常,返回友好提示:
[HttpPost] public IActionResult ConfirmCancelBooking(int id) { string fullUsername = User.Identity.Name; var booking = _context.Bookings.FirstOrDefault(b => b.Id == id && b.Username == fullUsername); if (booking == null) { return NotFound("预订不存在或您无权限删除"); } try { _context.Bookings.Remove(booking); _context.SaveChanges(); TempData["SuccessMsg"] = "预订已成功取消"; return RedirectToAction("Index"); } catch (Exception ex) { TempData["ErrorMsg"] = $"取消失败:{ex.Message}"; return View("CancelBooking", booking); } }
3. 视图添加状态提示
在视图中增加成功/错误消息显示:
@{ ViewBag.Title = "Cancel Booking"; } @if (TempData["SuccessMsg"] != null) { <div class="alert alert-success">@TempData["SuccessMsg"]</div> } @if (TempData["ErrorMsg"] != null) { <div class="alert alert-danger">@TempData["ErrorMsg"]</div> } <h2>Cancel Booking</h2> <p>Are you sure you want to cancel your booking for @Model.SelectedDate?</p> @using (Html.BeginForm("ConfirmCancelBooking", "Booking", FormMethod.Post)) { @Html.HiddenFor(model => model.Id) <input type="submit" value="Confirm Cancellation" class="btn btn-danger" /> <a href="@Url.Action("Index", "Booking")" class="btn btn-secondary">Back to Bookings</a> }
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

