Présentation de pages Web ASP.NET - Suppression de données de base de données

par Tom FitzMacken

Ce tutoriel vous montre comment supprimer une entrée de base de données individuelle. Il part du principe que vous avez terminé la série via la mise à jour des données de base de données dans pages Web ASP.NET.

Ce que vous allez apprendre :

  • Comment sélectionner un enregistrement individuel dans une liste d’enregistrements.
  • Comment supprimer un enregistrement unique d’une base de données.
  • Comment vérifier qu’un bouton spécifique a été cliqué dans un formulaire.

Fonctionnalités/technologies abordées :

  • L’assistance WebGrid .
  • Commande SQL Delete .
  • Méthode Database.Execute d’exécution d’une commande SQL Delete .

Contenu

Dans le tutoriel précédent, vous avez appris à mettre à jour un enregistrement de base de données existant. Ce didacticiel est similaire, sauf qu’au lieu de mettre à jour l’enregistrement, vous allez le supprimer. Les processus sont beaucoup identiques, sauf que la suppression est plus simple, de sorte que ce didacticiel sera court.

Dans la page Films , vous allez mettre à jour l’assistance WebGrid afin qu’il affiche un lien Supprimer en regard de chaque film pour accompagner le lien Modifier que vous avez ajouté précédemment.

Page Films montrant un lien Supprimer pour chaque film

Comme pour la modification, lorsque vous cliquez sur le lien Supprimer , vous accédez à une autre page, où les informations de film sont déjà dans un formulaire :

Supprimer la page Film avec un film affiché

Vous pouvez ensuite cliquer sur le bouton pour supprimer l’enregistrement définitivement.

Vous allez commencer par ajouter un lien Supprimer à l’assistance WebGrid . Ce lien est similaire au lien Modifier que vous avez ajouté dans un didacticiel précédent.

Ouvrez le fichier Movies.cshtml .

Modifiez le WebGrid balisage dans le corps de la page en ajoutant une colonne. Voici le balisage modifié :

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

La nouvelle colonne est celle-ci :

grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)

La façon dont la grille est configurée, la colonne Modifier est la plus à gauche dans la grille et la colonne Supprimer est la plus à droite. (Il y a une virgule après la Year colonne maintenant, si vous ne l’avez pas remarqué.) Il n’y a rien de spécial sur l’endroit où ces colonnes de lien vont, et vous pouvez aussi facilement les mettre à côté les uns des autres. Dans ce cas, ils sont séparés pour les rendre plus difficiles à mélanger.

Page Films avec des liens Modifier et Détails marqués pour montrer qu’ils ne sont pas à côté les uns des autres

La nouvelle colonne affiche un lien (<a> élément) dont le texte indique « Delete ». La cible du lien (son href attribut) est du code qui se résout finalement à quelque chose comme cette URL, avec la id valeur différente pour chaque film :

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

Ce lien appelle une page nommée DeleteMovie et la transmet à l’ID du film que vous avez sélectionné.

Ce didacticiel ne décrit pas en détail la façon dont ce lien est construit, car il est presque identique au lien Modifier du didacticiel précédent (mise à jour des données de base de données dans pages Web ASP.NET).

Création de la page Supprimer

Vous pouvez maintenant créer la page qui sera la cible du lien Supprimer dans la grille.

Remarque

Important La technique de première sélection d’un enregistrement à supprimer, puis l’utilisation d’une page et d’un bouton distincts pour confirmer que le processus est extrêmement important pour la sécurité. Comme vous l’avez lu dans les didacticiels précédents, vous devez toujours effectuer toute modification apportée à votre site web à l’aide d’un formulaire, c’est-à-dire à l’aide d’une opération HTTP POST. Si vous avez rendu possible de modifier le site simplement en cliquant sur un lien (autrement dit, à l’aide d’une opération GET), les utilisateurs pouvaient effectuer des demandes simples à votre site et supprimer vos données. Même un analyseur de moteur de recherche qui indexe votre site peut supprimer par inadvertance des données simplement en suivant des liens.

Lorsque votre application permet aux utilisateurs de modifier un enregistrement, vous devez présenter l’enregistrement à l’utilisateur pour modification de toute façon. Mais vous pourriez être tenté d’ignorer cette étape pour supprimer un enregistrement. N’ignorez pas cette étape. (Il est également utile aux utilisateurs de voir l’enregistrement et de confirmer qu’ils suppriment l’enregistrement qu’ils ont prévu.)

Dans un ensemble de tutoriels ultérieur, vous verrez comment ajouter des fonctionnalités de connexion afin qu’un utilisateur ait à se connecter avant de supprimer un enregistrement.

Créez une page nommée DeleteMovie.cshtml et remplacez ce qui se trouve dans le fichier par le balisage suivant :

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

Ce balisage est semblable aux pages EditMovie , sauf qu’au lieu d’utiliser des zones de texte (<input type="text">), le balisage inclut des <span> éléments. Il n’y a rien ici à modifier. Tout ce que vous devez faire est d’afficher les détails du film afin que les utilisateurs puissent s’assurer qu’ils suppriment le film approprié.

Le balisage contient déjà un lien qui permet à l’utilisateur de revenir à la page de référencement de films.

Comme dans la page EditMovie , l’ID du film sélectionné est stocké dans un champ masqué. (Il est passé dans la page en premier lieu en tant que valeur de chaîne de requête.) Html.ValidationSummary Un appel affiche des erreurs de validation. Dans ce cas, l’erreur peut être qu’aucun ID de film n’a été transmis à la page ou que l’ID de film n’est pas valide. Cette situation peut se produire si quelqu’un a exécuté cette page sans sélectionner d’abord un film dans la page Films .

La légende du bouton est Delete Movie et son attribut de nom est défini sur buttonDelete. L’attribut name sera utilisé dans le code pour identifier le bouton qui a envoyé le formulaire.

Vous devrez écrire du code sur 1) lire les détails du film lorsque la page est affichée pour la première fois et 2) supprimer réellement le film lorsque l’utilisateur clique sur le bouton.

Ajout de code pour lire un seul film

En haut de la page DeleteMovie.cshtml , ajoutez le bloc de code suivant :

@{
    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.");
        }
    }
}

Ce balisage est identique au code correspondant dans la page EditMovie . Il obtient l’ID de film de la chaîne de requête et utilise l’ID pour lire un enregistrement à partir de la base de données. Le code inclut le test de validation (IsInt() et row != null) pour vous assurer que l’ID de film transmis à la page est valide.

N’oubliez pas que ce code ne doit exécuter que la première fois que la page s’exécute. Vous ne souhaitez pas relire l’enregistrement vidéo à partir de la base de données lorsque l’utilisateur clique sur le bouton Supprimer le film . Par conséquent, le code à lire est à l’intérieur d’un test qui indique if(!IsPost) : autrement dit, si la demande n’est pas une opération post-opération (soumission de formulaire).

Ajout de code pour supprimer le film sélectionné

Pour supprimer le film lorsque l’utilisateur clique sur le bouton, ajoutez le code suivant juste à l’intérieur de l’accolade fermante du @ bloc :

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");
}

Ce code est similaire au code pour la mise à jour d’un enregistrement existant, mais plus simple. Le code exécute essentiellement une instruction SQL Delete .

Comme dans la page EditMovie , le code se trouve dans un if(IsPost) bloc. Cette fois, la if() condition est un peu plus compliquée :

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

Il y a deux conditions ici. La première est que la page est soumise, comme vous l’avez vu précédemment if(IsPost).

La deuxième condition est !Request["buttonDelete"].IsEmpty(), ce qui signifie que la requête a un objet nommé buttonDelete. Certes, il s’agit d’un moyen indirect de tester le bouton qui a soumis le formulaire. Si un formulaire contient plusieurs boutons d’envoi, seul le nom du bouton qui a été cliqué apparaît dans la demande. Par conséquent, logiquement, si le nom d’un bouton particulier apparaît dans la demande ( ou comme indiqué dans le code, si ce bouton n’est pas vide), c’est le bouton qui a envoyé le formulaire.

L’opérateur && signifie « et » (AND logique). Par conséquent, la condition entière if est ...

Cette demande est un billet (et non une demande de première fois)

AND

Le buttonDeletebouton était le bouton qui a envoyé le formulaire.

Ce formulaire (en fait, cette page) ne contient qu’un seul bouton, de sorte que le test supplémentaire pour buttonDelete lequel il n’est pas techniquement nécessaire. Toutefois, vous êtes sur le point d’effectuer une opération qui supprimera définitivement les données. Vous souhaitez donc être aussi sûr que possible que vous effectuez l’opération uniquement lorsque l’utilisateur l’a explicitement demandé. Par exemple, supposons que vous avez développé cette page ultérieurement et ajouté d’autres boutons. Même ensuite, le code qui supprime le film s’exécute uniquement si le buttonDelete bouton a été cliqué.

Comme dans la page EditMovie , vous obtenez l’ID du champ masqué, puis exécutez la commande SQL. La syntaxe de l’instruction Delete est la suivante :

DELETE FROM table WHERE ID = value

Il est essentiel d’inclure la WHERE clause et l’ID. Si vous quittez la clause WHERE, tous les enregistrements de la table sont supprimés. Comme vous l’avez vu, vous passez la valeur d’ID à la commande SQL à l’aide d’un espace réservé.

Test du processus de suppression de film

Vous pouvez maintenant tester. Exécutez la page Films , puis cliquez sur Supprimer en regard d’un film. Lorsque la page DeleteMovie s’affiche, cliquez sur Supprimer le film.

Page Supprimer le film avec le bouton Supprimer le film mis en surbrillance

Lorsque vous cliquez sur le bouton, le code supprime les films et retourne à la liste des films. Vous pouvez rechercher le film supprimé et confirmer qu’il a été supprimé.

Prochaine étape

Le tutoriel suivant vous montre comment donner à toutes les pages de votre site une apparence et une disposition courantes.

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

Liste complète de la page 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>

Ressources complémentaires