Я работаю над приложением ASP.NET MVC и столкнулся с проблемой удаления строк.
Вот конкретный сценарий: у меня есть две таблицы базы данных: AvailableDates
и Bookings
.
В пользовательском интерфейсе пользователи могут просматривать доступные даты. Когда пользователь выбирает дату для удаления, система должна удалить соответствующую строку из таблицы 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>
}
Я не уверен, что ваш пример неполный, но вы не предоставили код кнопки/формы, который по умолчанию может быть вызовом GET, для которого действие вашего контроллера не настроено.
Пробовали [HttpPost("ConfirmCancelBooking")]
? Теперь для метода можно определить путь по умолчанию для контроллера с помощью метода POST (без ConfirmCancelBooking
в пути). Более того, вы можете использовать для этого метод HTTP DELETE [HttpDelete("ConfirmCancelBooking")]
Я на самом деле попробовал, но это не сработало. Я добавил вид здесь.
Почему бы вам просто не выполнить отладку и не найти причину ошибки?
Проблема может быть связана с добавленным вами перенаправлением на действие. Я изменил тип возврата и удалил перенаправление в конце
Также похоже, что вы забыли указать идентификатор бронирования.
[HttpPost]
public Task<bool> ConfirmCancelBooking([FromBody] int bookingId)
{
string fullUsername = User.Identity.Name;
var booking = _context.Bookings.SingleOrDefault(b => b.Id == bookingId && b.Username == fullUsername);
if (booking == null)
{
return false();
}
_context.Bookings.Remove(booking);
_context.SaveChanges();
return true;
}
Это единственный элемент, который позволяет вам перемещаться. Если это не решит вашу проблему, обновите и добавьте код кнопки.
Также вы можете просто сделать _context.Remove(booking)
, это работает так же, как _context.Bookings.Remove(booking)
Привет @Kaiwinta, спасибо за совет! Я виноват, что не упомянул вид раньше.
Однако в вашем действии ConfirmCancelBooking
параметром является bookingId
по следующим причинам:
@Html.HiddenFor(model => model.Id)
Имя скрытого ввода будет id
, что означает, что значение bookingId
при попадании в действие контроллера будет 0
.
Итак, когда вы выполняете запрос к базе данных:
var booking = _context
.Bookings
.SingleOrDefault(b => b.Id == bookingId
&& b.Username == fullUsername);
Вы будете искать Booking
с Id
из 0
, в существовании которого я сомневаюсь. Это будет означать, что var booking
есть null
и, следовательно, ваша отметка booking
null
под ним будет true
, что приведет к 404
.
Попробуйте изменить его на следующее:
public IActionResult ConfirmCancelBooking(int id)
{
// Your code
}
Несколько предложений.
NotFound
. Например:return NotFound($"No booking found for ID {id}");
ILogger
, чтобы добавить вывод журнала для помощи в отладке.Спасибо, @Peppermintology, за исправления! Они полностью сработали. Также оцените предложения.
Судя по опубликованному вами URL-адресу, вы, похоже, не передаете параметр bookingId.