Введение веб-страницы ASP.NET — удаление данных базы данных
В этом руководстве показано, как удалить отдельную запись базы данных. Предполагается, что серия завершена с помощью обновления данных базы данных в веб-страницы ASP.NET.
Из этого руководства вы узнаете, как выполнять такие задачи:
- Как выбрать отдельную запись из списка записей.
- Удаление одной записи из базы данных.
- Как проверить, была ли нажата определенная кнопка в форме.
Рассматриваются функции и технологии:
- Помощник
WebGrid
.- Команда SQL
Delete
.- Метод
Database.Execute
для выполнения команды SQLDelete
.
Что вы создадите
В предыдущем руководстве вы узнали, как обновить существующую запись базы данных. Это руководство аналогично, за исключением того, что вместо обновления записи вы удалите ее. Процессы очень одинаковы, за исключением того, что удаление проще, поэтому это руководство будет коротким.
На странице "Фильмы" вы обновите WebGrid
вспомогательный элемент, чтобы он отображал ссылку "Удалить" рядом с каждым фильмом, чтобы сопровождать добавленную ранее ссылку "Изменить".
Как и при редактировании, при нажатии ссылки " Удалить " вы перейдете на другую страницу, где информация о фильме уже находится в форме:
Затем можно нажать кнопку, чтобы окончательно удалить запись.
Добавление ссылки на удаление в список фильмов
Сначала вы добавите ссылку "Удалить " в вспомогательный WebGrid
элемент. Эта ссылка похожа на ссылку "Изменить", добавленную в предыдущем руководстве.
Откройте файл Movies.cshtml.
Измените разметку WebGrid
в тексте страницы, добавив столбец. Ниже приведена измененная разметка:
@grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year"),
grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)
)
)
Новый столбец — это один из следующих вариантов:
grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)
Способ настройки сетки, столбец "Изменить" находится в левой части сетки, а столбец Delete является самым правым. (Теперь после столбца Year
есть запятая, если вы этого не заметили.) Нет ничего особенного в том, где эти столбцы ссылки идти, и вы можете так же легко положить их рядом друг с другом. В этом случае они отделены, чтобы сделать их сложнее, чтобы смешаться.
В новом столбце показана ссылка (<a>
элемент), текст которого говорит "Удалить". Цель ссылки (его href
атрибут) — это код, который в конечном счете разрешает что-то вроде этого URL-адреса с значением id
для каждого фильма:
http://localhost:43097/DeleteMovie?id=7
Эта ссылка вызывает страницу с именем DeleteMovie и передает ему идентификатор выбранного фильма.
В этом руководстве не будет подробно описано, как эта ссылка создана, так как она почти идентична ссылке "Изменить" из предыдущего руководства (обновление данных базы данных в веб-страницы ASP.NET).
Создание страницы удаления
Теперь вы можете создать страницу, которая будет целевой для ссылки "Удалить " в сетке.
Примечание.
Важно, чтобы сначала выбрать запись для удаления, а затем использовать отдельную страницу и кнопку, чтобы убедиться, что процесс крайне важен для безопасности. Как вы читали в предыдущих руководствах, любое изменение веб-сайта должно всегда выполняться с помощью формы — то есть с помощью операции HTTP POST. Если вы сделали возможным изменить сайт, щелкнув ссылку (т. е. с помощью операции GET), пользователи могут выполнять простые запросы к сайту и удалять данные. Даже обходчик поисковой системы, который индексирует ваш сайт, может случайно удалить данные только по ссылкам.
Когда приложение позволяет пользователям изменять запись, необходимо представить запись пользователю для редактирования. Но вам может потребоваться пропустить этот шаг для удаления записи. Не пропустите этот шаг, хотя. (Это также полезно для пользователей, чтобы просмотреть запись и убедиться, что они удаляют запись, которую они намеревались.)
В следующем наборе учебников вы увидите, как добавить функции входа, чтобы пользователь должен был войти перед удалением записи.
Создайте страницу с именем DeleteMovie.cshtml и замените то, что находится в файле, на следующую разметку:
<html>
<head>
<title>Delete a Movie</title>
</head>
<body>
<h1>Delete a Movie</h1>
@Html.ValidationSummary()
<p><a href="~/Movies">Return to movie listing</a></p>
<form method="post">
<fieldset>
<legend>Movie Information</legend>
<p><span>Title:</span>
<span>@title</span></p>
<p><span>Genre:</span>
<span>@genre</span></p>
<p><span>Year:</span>
<span>@year</span></p>
<input type="hidden" name="movieid" value="@movieId" />
<p><input type="submit" name="buttonDelete" value="Delete Movie" /></p>
</fieldset>
</form>
</body>
</html>
Эта разметка похожа на страницы EditMovie , за исключением того, что вместо использования текстовых полей (<input type="text">
), разметка включает <span>
элементы. Здесь нет ничего, чтобы изменить. Все, что нужно сделать, — отобразить сведения о фильме, чтобы пользователи могли убедиться, что они удаляют правильный фильм.
Разметка уже содержит ссылку, которая позволяет пользователю вернуться на страницу списка фильмов.
Как и на странице EditMovie , идентификатор выбранного фильма хранится в скрытом поле. (Он передается на страницу в первую очередь в качестве значения строки запроса.) Html.ValidationSummary
Есть вызов, который будет отображать ошибки проверки. В этом случае ошибка может быть, что идентификатор фильма не был передан на страницу или что идентификатор фильма недопустим. Эта ситуация может произойти, если кто-то запустил эту страницу без первого выбора фильма на странице "Фильмы ".
Заголовок кнопки — Delete Movie, а его атрибут имени имеет значение buttonDelete
. Атрибут name
будет использоваться в коде для идентификации кнопки, отправленной формы.
Вам придется написать код до 1) прочитать сведения о фильме при первом отображении страницы и 2) фактически удалить фильм, когда пользователь нажимает кнопку.
Добавление кода для чтения одного фильма
В верхней части страницы DeleteMovie.cshtml добавьте следующий блок кода:
@{
var title = "";
var genre = "";
var year = "";
var movieId = "";
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()){
movieId = Request.QueryString["ID"];
var db = Database.Open("WebPagesMovies");
var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
var row = db.QuerySingle(dbCommand, movieId);
if(row != null) {
title = row.Title;
genre = row.Genre;
year = row.Year;
}
else{
Validation.AddFormError("No movie was found for that ID.");
}
}
else{
Validation.AddFormError("No movie was found for that ID.");
}
}
}
Эта разметка совпадает с соответствующим кодом на странице EditMovie . Он получает идентификатор фильма из строки запроса и использует идентификатор для чтения записи из базы данных. Код включает тест проверки (IsInt()
и row != null
), чтобы убедиться, что идентификатор фильма, передаваемый на страницу, является допустимым.
Помните, что этот код должен выполняться только при первом запуске страницы. Вы не хотите повторно читать запись фильма из базы данных, когда пользователь нажимает кнопку "Удалить фильм ". Поэтому код для чтения фильма находится внутри теста, который говорит if(!IsPost)
, то есть, если запрос не является операцией после отправки формы.
Добавление кода для удаления выбранного фильма
Чтобы удалить фильм, когда пользователь нажимает кнопку, добавьте следующий код в закрывающую скобку @
блока:
if(IsPost && !Request["buttonDelete"].IsEmpty()){
movieId = Request.Form["movieId"];
var db = Database.Open("WebPagesMovies");
var deleteCommand = "DELETE FROM Movies WHERE ID = @0";
db.Execute(deleteCommand, movieId);
Response.Redirect("~/Movies");
}
Этот код аналогичен коду для обновления существующей записи, но проще. В основном код выполняет инструкцию SQL Delete
.
Как и на странице EditMovie , код находится в блоке if(IsPost)
. На этот раз if()
условие немного сложнее:
if(IsPost && !Request["buttonDelete"].IsEmpty())
Здесь есть два условия. Первым является то, что страница отправляется, как вы видели ранее . if(IsPost)
Второе условие — это !Request["buttonDelete"].IsEmpty()
означает, что запрос имеет объект с именем buttonDelete
. По общему признанию, это косвенный способ тестирования, который кнопка отправила форму. Если форма содержит несколько кнопок отправки, в запросе отображается только имя кнопки, которая была нажата. Таким образом, логически, если имя определенной кнопки отображается в запросе или как указано в коде, если эта кнопка не пуста, это кнопка, которая отправила форму.
Оператор &&
означает "and" (логическое И). Поэтому все if
условие ...
Этот запрос является записью (не первым запросом)
И
Кнопка buttonDelete
была кнопкой, которая отправила форму.
Эта форма (на самом деле эта страница) содержит только одну кнопку, поэтому дополнительный тест buttonDelete
для технически не требуется. Тем не менее, вы будете выполнять операцию, которая будет окончательно удалять данные. Таким образом, вы хотите быть настолько уверены, что выполняете операцию только в том случае, если пользователь явно запросил его. Например, предположим, что вы расширили эту страницу позже и добавили в нее другие кнопки. Даже тогда код, который удаляет фильм, будет выполняться только в том случае, если buttonDelete
кнопка была нажата.
Как и на странице EditMovie , вы получите идентификатор из скрытого поля, а затем выполните команду SQL. Синтаксис инструкции Delete
:
DELETE FROM table WHERE ID = value
Важно включить WHERE
предложение и идентификатор. При выходе из предложения WHERE все записи в таблице будут удалены. Как вы видели, вы передаете значение идентификатора команде SQL с помощью заполнителя.
Тестирование процесса удаления фильма
Теперь можно протестировать. Запустите страницу "Фильмы " и нажмите кнопку " Удалить рядом с фильмом". Когда появится страница DeleteMovie, нажмите кнопку "Удалить фильм".
При нажатии кнопки код удаляет фильмы и возвращается в список фильмов. Там можно найти удаленный фильм и убедиться, что он удален.
Ближайший следующий
В следующем руководстве показано, как предоставить всем страницам на сайте общий вид и макет.
Полное описание страницы фильма (обновлено с помощью ссылок на удаление)
@{
var db = Database.Open("WebPagesMovies") ;
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";
if(!Request.QueryString["searchGenre"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
searchTerm = Request.QueryString["searchGenre"];
}
if(!Request.QueryString["searchTitle"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
searchTerm = "%" + Request.QueryString["searchTitle"] + "%";
}
var selectedData = db.Query(selectCommand, searchTerm);
var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Movies</title>
<style type="text/css">
.grid { margin: 4px; border-collapse: collapse; width: 600px; }
.grid th, .grid td { border: 1px solid #C0C0C0; padding: 5px; }
.head { background-color: #E8E8E8; font-weight: bold; color: #FFF; }
.alt { background-color: #E8E8E8; color: #000; }
</style>
</head>
<body>
<h1>Movies</h1>
<form method="get">
<div>
<label for="searchGenre">Genre to look for:</label>
<input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />
<input type="Submit" value="Search Genre" /><br/>
(Leave blank to list all movies.)<br/>
</div>
<div>
<label for="SearchTitle">Movie title contains the following:</label>
<input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
<input type="Submit" value="Search Title" /><br/>
</div>
</form>
<div>
@grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year"),
grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)
)
)
</div>
<p>
<a href="~/AddMovie">Add a movie</a>
</p>
</body>
</html>
Полное описание страницы DeleteMovie
@{
var title = "";
var genre = "";
var year = "";
var movieId = "";
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()){
movieId = Request.QueryString["ID"];
var db = Database.Open("WebPagesMovies");
var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
var row = db.QuerySingle(dbCommand, movieId);
if(row != null) {
title = row.Title;
genre = row.Genre;
year = row.Year;
}
else{
Validation.AddFormError("No movie was found for that ID.");
}
}
else{
Validation.AddFormError("No movie was found for that ID.");
}
}
if(IsPost && !Request["buttonDelete"].IsEmpty()){
movieId = Request.Form["movieId"];
var db = Database.Open("WebPagesMovies");
var deleteCommand = "DELETE FROM Movies WHERE ID = @0";
db.Execute(deleteCommand, movieId);
Response.Redirect("~/Movies");
}
}
<html>
<head>
<title>Delete a Movie</title>
</head>
<body>
<h1>Delete a Movie</h1>
@Html.ValidationSummary()
<p><a href="~/Movies">Return to movie listing</a></p>
<form method="post">
<fieldset>
<legend>Movie Information</legend>
<p><span>Title:</span>
<span>@title</span></p>
<p><span>Genre:</span>
<span>@genre</span></p>
<p><span>Year:</span>
<span>@year</span></p>
<input type="hidden" name="movieid" value="@movieId" />
<p><input type="submit" name="buttonDelete" value="Delete Movie" /></p>
</fieldset>
<p><a href="~/Movies">Return to movie listing</a></p>
</form>
</body>
</html>
Дополнительные ресурсы
- Общие сведения о веб-программировании ASP.NET с помощью синтаксиса Razor
- Инструкция SQL DELETE на сайте W3Schools