Введение веб-страницы ASP.NET-удаление данных базы данных

от Tom фитзмаккен

В этом учебнике показано, как удалить отдельную запись базы данных. Предполагается, что вы выполнили цикл по обновлению данных базы данных в веб-страницы ASP.NET.

Из этого руководства вы узнаете, как выполнять такие задачи:

  • Выбор отдельной записи из списка записей.
  • Удаление одной записи из базы данных.
  • Как проверить, была ли нажата определенная кнопка в форме.

Обсуждаемые функции и технологии:

  • Вспомогательный метод WebGrid.
  • Команда SQL Delete.
  • Метод Database.Execute для выполнения команды SQL Delete.

Что вы создадите

В предыдущем руководстве вы узнали, как обновить существующую запись базы данных. Этот учебник аналогичен, но вместо обновления записи вы удалите его. Процессы во многом одинаковы, за исключением того, что удаление упрощается, поэтому этот учебник будет небольшим.

На странице фильмов вы обновите вспомогательную функцию WebGrid, чтобы она отображала ссылку Delete (удалить ) рядом с каждым фильмом, сопровождающую ссылку на изменение , добавленную ранее.

Страница фильмов, на которой показана ссылка для удаления каждого фильма

Как и при редактировании, при щелчке ссылки Удалить выполняется переход на другую страницу, где сведения о фильме уже находятся в форме:

Удаление страницы фильма с отображаемым фильмом

Затем можно нажать кнопку, чтобы удалить запись без возможности восстановления.

Начнем с добавления ссылки Delete в вспомогательную функцию 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>)

Способ настройки сетки, столбец « Правка » является крайним левым в сетке, а столбец « Удаление » — крайний правый. (В случае, если вы не заметите, есть запятая после Year столбца.) Нет ничего особенного, о том, где находятся эти ссылочные столбцы, и можно легко разместить их рядом друг с другом. В этом случае они разделяются, чтобы их было сложнее приступить к изприятию.

Страница "фильмы" с ссылками "Изменить" и "подробности", помеченными, чтобы показывать, что они не находятся рядом

В новом столбце отображается ссылка (<a> элемент), текст которой говорит «DELETE». Целевой объект ссылки (его атрибут href) — это код, который, в конечном итоге, разрешается в нечто вроде этого URL-адреса, и id значение для каждого фильма отличается.

http://localhost:43097/DeleteMovie?id=7

Эта ссылка приведет к вызову страницы с именем делетемовие и передаче ей идентификатора выбранного фильма.

В этом учебнике не будет подробно рассмотрено, как создается эта ссылка, так как она почти идентична ссылке Edit из предыдущего руководства (Обновление данных базы данных в веб-страницы ASP.NET).

Создание страницы удаления

Теперь можно создать страницу, которая будет целевым объектом для ссылки Delete в сетке.

Note

Важно! Метод сначала выбирает удаляемую запись, а затем использует отдельную страницу и кнопку для подтверждения того, что процесс чрезвычайно важен для обеспечения безопасности. Как вы прочитали в предыдущих учебных курсах, внесение изменений на веб-сайт всегда должно выполняться с помощью формы — то есть с помощью операции HTTP POST. Если вы сделали возможным изменение сайта просто щелкнув ссылку (то есть с помощью операции GET), пользователи смогут выполнять простые запросы к сайту и удалять данные. Даже модуль поиска, который индексирует ваш сайт, может случайно удалить данные только по следующим ссылкам.

Когда приложение позволяет пользователям изменять запись, в любом случае необходимо предоставить пользователю запись для редактирования. Но вы, возможно, пропустите этот шаг, чтобы удалить запись. Но не пропустите этот шаг. (Кроме того, пользователям рекомендуется просматривать записи и подтверждать, что они удаляют записи, которые они предполагали.)

В последующем наборе руководств вы узнаете, как добавить функции входа в систему, чтобы пользователь мог выполнить вход перед удалением записи.

Создайте страницу с именем делетемовие. 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>

Эта разметка похожа на страницы едитмовие , за исключением того, что вместо использования текстовых полей (<input type="text">) разметка включает <span> элементы. Здесь нет ничего редактировать. Все, что нужно сделать, — отобразить сведения о фильме, чтобы пользователи могли убедиться, что они удаляют нужный фильм.

Разметка уже содержит ссылку, которая позволяет пользователю вернуться на страницу со списком фильмов.

Как и на странице едитмовие , идентификатор выбранного фильма хранится в скрытом поле. (Он передается на страницу в первом месте как значение строки запроса). Есть Html.ValidationSummary вызов, который будет отображать ошибки проверки. В этом случае ошибка может быть вызвана тем, что на страницу не был передан идентификатор фильма или что идентификатор фильма недопустим. Такая ситуация может возникнуть, если кто-то запустил эту страницу без предварительного выбора фильма на странице фильмов .

Заголовок кнопки — удалить фильм, а его атрибут name имеет значение buttonDelete. Атрибут name будет использоваться в коде для распознавания кнопки, которая отправила форму.

Вам потребуется написать код в 1) прочитать сведения о фильме при первом отображении страницы и 2) удалить фильм, когда пользователь нажмет кнопку.

Добавление кода для чтения одного фильма

В верхней части страницы делетемовие. 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.");
        }
    }
}

Эта разметка аналогична соответствующему коду на странице едитмовие . Он получает идентификатор фильма из строки запроса и использует идентификатор для чтения записи из базы данных. Код включает проверочный тест (IsInt() и row != null), чтобы убедиться, что идентификатор фильма, передаваемый на страницу, является допустимым.

Помните, что этот код должен выполняться только при первом запуске страницы. Вы не хотите повторно считывать запись фильма из базы данных, когда пользователь нажимает кнопку удалить фильм . Таким образом, код для чтения фильма находится внутри теста, который говорит if(!IsPost) — то есть, Если запрос не является операцией POST (отправка формы) .

Добавление кода для удаления выбранного фильма

Чтобы удалить фильм при нажатии кнопки, добавьте следующий код непосредственно в закрывающую фигурную скобку блока @:

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.

Как и на странице едитмовие , код находится в блоке if(IsPost). На этот раз if() условие немного сложнее:

if(IsPost && !Request["buttonDelete"].IsEmpty())

Здесь есть два условия. Первый заключается в том, что страница отправляется, как показано выше — if(IsPost).

Второе условие — !Request["buttonDelete"].IsEmpty(), то есть запрос содержит объект с именем buttonDelete. Разумеется, это косвенный способ проверки того, какая кнопка отправила форму. Если форма содержит несколько кнопок отправки, в запросе отображается только имя кнопки, которая была нажата. Таким образом, логически, если имя определенной кнопки появляется в запросе — или как указано в коде, если эта кнопка не пуста — это кнопка, которая отправляла форму.

Оператор && означает "and" (логическое и). Таким образом, все if условие имеет значение...

Этот запрос является сообщением POST (не запросом в первый раз)

AND

Кнопка buttonDeleteбыла отправлена в форму.

Эта форма (на самом деле, эта страница) содержит только одну кнопку, поэтому дополнительный тест buttonDelete технически не является обязательным. Тем не менее вы собираетесь выполнить операцию, которая будет окончательно удалять данные. Так что вы должны быть уверены, что операция выполняется только в том случае, если пользователь явно запросил ее. Например, предположим, что вы развернули эту страницу позже и добавили в нее другие кнопки. Даже после этого код, который удаляет фильм, будет выполняться только в том случае, если была нажата кнопка buttonDelete.

Как и на странице едитмовие , вы получаете идентификатор из скрытого поля, а затем выполняете команду SQL. Синтаксис инструкции Delete:

DELETE FROM table WHERE ID = value

Крайне важно включать предложение WHERE и идентификатор. Если оставить предложение WHERE, все записи в таблице будут удалены. Как вы видите, значение идентификатора передается команде SQL с помощью заполнителя.

Тестирование процесса удаления фильма

Теперь можно протестировать. Запустите страницу фильмов и щелкните Удалить рядом с фильмом. Когда появится страница делетемовие , щелкните удалить фильм.

Удаление страницы фильма с выделенной кнопкой "удалить фильм"

При нажатии кнопки код удаляет фильмы и возвращает их в список фильмов. Там можно найти удаленный фильм и убедиться, что он был удален.

Далее

В следующем учебнике показано, как дать всем страницам на сайте общий вид и макет.

@{
    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>

Полный список для страницы Делетемовие

@{
    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>

Дополнительные ресурсы