Partager via


Présentation de pages Web ASP.NET - Mise à jour des données de base de données

par Tom FitzMacken

Ce tutoriel vous montre comment mettre à jour (modifier) une entrée de base de données existante lorsque vous utilisez pages Web ASP.NET (Razor). Il suppose que vous avez terminé la série en entrant des données à l’aide de formulaires à l’aide de pages Web ASP.NET.

Ce que vous allez apprendre :

  • Comment sélectionner un enregistrement individuel dans l’assistance WebGrid .
  • Comment lire un enregistrement unique à partir d’une base de données.
  • Comment précharger un formulaire avec des valeurs de l’enregistrement de base de données.
  • Comment mettre à jour un enregistrement existant dans une base de données.
  • Comment stocker des informations dans la page sans les afficher.
  • Comment utiliser un champ masqué pour stocker des informations.

Fonctionnalités/technologies abordées :

  • L’assistance WebGrid .
  • Commande SQL Update .
  • Méthode Database.Execute
  • Champs masqués (<input type="hidden">).

Contenu

Dans le tutoriel précédent, vous avez appris à ajouter un enregistrement à une base de données. Ici, vous allez apprendre à afficher un enregistrement à modifier. Dans la page Films , vous allez mettre à jour l’assistance WebGrid afin qu’il affiche un lien Modifier en regard de chaque film :

Affichage WebGrid incluant un lien « Modifier » pour chaque film

Lorsque vous cliquez sur le lien Modifier , vous accédez à une autre page, où les informations du film se trouvent déjà dans un formulaire :

Page Modifier le film montrant le film à modifier

Vous pouvez modifier n’importe quelle valeur. Lorsque vous envoyez les modifications, le code de la page met à jour la base de données et vous ramène à la liste des films.

Cette partie du processus fonctionne presque exactement comme la page AddMovie.cshtml que vous avez créée dans le tutoriel précédent.

Il existe plusieurs façons d’implémenter un moyen de modifier un film individuel. L’approche indiquée a été choisie parce qu’elle est facile à implémenter et à comprendre.

Pour commencer, vous allez mettre à jour la page Films afin que chaque liste de films contienne également un lien Modifier .

Ouvrez le fichier Movies.cshtml .

Dans le corps de la page, modifiez le WebGrid balisage 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")
    )
)

La nouvelle colonne est celle-ci :

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

Le point de cette colonne est d’afficher un lien (<a> élément) dont le texte indique « Modifier ». Ce que nous recherchons, c’est de créer un lien qui ressemble à ce qui suit lorsque la page s’exécute, avec une id valeur différente pour chaque film :

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

Ce lien appelle une page nommée EditMovie et transmet la chaîne ?id=7 de requête à cette page.

La syntaxe de la nouvelle colonne peut sembler un peu complexe, mais c’est uniquement parce qu’elle regroupe plusieurs éléments. Chaque élément individuel est simple. Si vous vous concentrez uniquement sur l’élément <a> , vous voyez ce balisage :

<a href="~/EditMovie?id=@item.ID)">Edit</a>

Informations d’arrière-plan sur le fonctionnement de la grille : la grille affiche des lignes, une pour chaque enregistrement de base de données, et elle affiche des colonnes pour chaque champ de l’enregistrement de base de données. Pendant la construction de chaque ligne de grille, l’objet item contient l’enregistrement de base de données (élément) pour cette ligne. Cette disposition vous donne un moyen dans le code d’obtenir les données de cette ligne. C’est ce que vous voyez ici : l’expression item.ID obtient la valeur ID de l’élément de base de données actuel. Vous pouvez obtenir l’une des valeurs de base de données (titre, genre ou année) de la même façon à l’aide item.Titlede , item.Genreou item.Year.

L’expression "~/EditMovie?id=@item.ID combine la partie codée en dur de l’URL cible (~/EditMovie?id=) avec cet ID dérivé dynamiquement. (Vous avez vu l’opérateur ~ dans le tutoriel précédent ; il s’agit d’un opérateur ASP.NET qui représente la racine du site web actuel.)

Le résultat est que cette partie du balisage dans la colonne produit simplement quelque chose comme le balisage suivant au moment de l’exécution :

href="/EditMovie?id=2"

Naturellement, la valeur réelle de id sera différente pour chaque ligne.

Création d’un affichage personnalisé pour une colonne grille

Revenez maintenant à la colonne de grille. Les trois colonnes que vous aviez initialement dans la grille affichaient uniquement des valeurs de données (titre, genre et année). Vous avez spécifié cet affichage en transmettant le nom de la colonne de base de données, par exemple . grid.Column("Title")

Cette nouvelle colonne Modifier le lien est différente. Au lieu de spécifier un nom de colonne, vous passez un format paramètre. Ce paramètre vous permet de définir le balisage que l’assistance WebGrid affichera avec la item valeur pour afficher les données de colonne en gras ou en vert ou dans le format souhaité. Par exemple, si vous souhaitez que le titre apparaisse en gras, vous pouvez créer une colonne comme cet exemple :

grid.Column(format:@<strong>@item.Title</strong>)

(Les différents @ caractères que vous voyez dans la format propriété marquent la transition entre le balisage et une valeur de code.)

Une fois que vous connaissez la format propriété, il est plus facile de comprendre comment la nouvelle colonne Modifier le lien est rassemblée :

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

La colonne se compose uniquement du balisage qui affiche le lien, ainsi que de certaines informations (l’ID) extraites de l’enregistrement de base de données pour la ligne.

Conseil

Paramètres nommés et paramètres positionnels pour une méthode

Souvent, lorsque vous avez appelé une méthode et lui avez passé des paramètres, vous avez simplement listé les valeurs de paramètres séparées par des virgules. Voici quelques exemples :

db.Execute(insertCommand, title, genre, year)

Validation.RequireField("title", "You must enter a title")

Nous n’avons pas mention le problème lorsque vous avez vu ce code pour la première fois, mais dans chaque cas, vous transmettez des paramètres aux méthodes dans un ordre spécifique, à savoir l’ordre dans lequel les paramètres sont définis dans cette méthode. Pour db.Execute et Validation.RequireFields, si vous mélangez l’ordre des valeurs que vous passez, vous obtiendrez un message d’erreur lors de l’exécution de la page, ou au moins des résultats étranges. Il est clair que vous devez connaître l’ordre dans lequel passer les paramètres. (Dans WebMatrix, IntelliSense peut vous aider à déterminer le nom, le type et l’ordre des paramètres.)

Au lieu de passer des valeurs dans l’ordre, vous pouvez utiliser des paramètres nommés. (La transmission des paramètres dans l’ordre est appelée utilisation de paramètres positionnels.) Pour les paramètres nommés, vous incluez explicitement le nom du paramètre lors du passage de sa valeur. Vous avez déjà utilisé des paramètres nommés plusieurs fois dans ces tutoriels. Par exemple :

var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3)

et

@grid.GetHtml(
    tableStyle: "grid",
    headerStyle: "head",
    alternatingRowStyle: "alt",
    columns: grid.Columns(
       grid.Column("Title"),
       grid.Column("Genre"),
       grid.Column("Year")
    )
)

Les paramètres nommés sont utiles pour quelques situations, en particulier lorsqu’une méthode prend de nombreux paramètres. L’une est lorsque vous souhaitez passer un ou deux paramètres seulement, mais les valeurs que vous souhaitez passer ne figurent pas parmi les premières positions de la liste des paramètres. Une autre situation consiste à rendre votre code plus lisible en transmettant les paramètres dans l’ordre qui vous convient le plus.

Évidemment, pour utiliser des paramètres nommés, vous devez connaître les noms des paramètres. WebMatrix IntelliSense peut vous afficher les noms, mais il ne peut pas les remplir pour vous.

Création de la page Modifier

Vous pouvez maintenant créer la page EditMovie . Lorsque les utilisateurs cliquent sur le lien Modifier, ils se retrouvent sur cette page.

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

<!DOCTYPE html>
<html>
  <head>
   <meta charset="utf-8" />
   <title>Edit a Movie</title>
    <style>
      .validation-summary-errors{
        border:2px dashed red;
        color:red;
        font-weight:bold;
        margin:12px;
      }
    </style>
  </head>
  <body>
    <h1>Edit a Movie</h1>
    @Html.ValidationSummary()
    <form method="post">
      <fieldset>
        <legend>Movie Information</legend>

        <p><label for="title">Title:</label>
           <input type="text" name="title" value="@title" /></p>

        <p><label for="genre">Genre:</label>
           <input type="text" name="genre" value="@genre" /></p>

        <p><label for="year">Year:</label>
           <input type="text" name="year" value="@year" /></p>

        <input type="hidden" name="movieid" value="@movieId" />

        <p><input type="submit" name="buttonSubmit" value="Submit Changes" /></p>
      </fieldset>
    </form>
  </body>
</html>

Ce balisage et ce code sont similaires à ceux que vous avez dans la page AddMovie . Il existe une petite différence dans le texte du bouton Envoyer. Comme pour la page AddMovie , un Html.ValidationSummary appel affiche les erreurs de validation le cas échéant. Cette fois, nous excluons les appels à Validation.Message, car les erreurs seront affichées dans le résumé de validation. Comme indiqué dans le tutoriel précédent, vous pouvez utiliser le résumé de validation et les messages d’erreur individuels dans différentes combinaisons.

Notez à nouveau que l’attribut method de l’élément <form> est défini sur post. Comme avec la page AddMovie.cshtml , cette page apporte des modifications à la base de données. Par conséquent, ce formulaire doit effectuer une POST opération. (Pour plus d’informations sur la différence entre GET les opérations et POST , consultez la barre latérale GET, POST et HTTP Verb Safety dans le tutoriel sur les formulaires HTML.)

Comme vous l’avez vu dans un tutoriel précédent, les value attributs des zones de texte sont définis avec du code Razor afin de les précharger. Cette fois,cependant, vous utilisez des variables telles title que et genre pour cette tâche au lieu de Request.Form["title"]:

<input type="text" name="title" value="@title" />

Comme précédemment, ce balisage précharge les valeurs de zone de texte avec les valeurs de film. Vous verrez dans un instant pourquoi il est pratique d’utiliser des variables cette fois au lieu d’utiliser l’objet Request .

Il existe également un <input type="hidden"> élément sur cette page. Cet élément stocke l’ID du film sans le rendre visible sur la page. L’ID est initialement passé à la page à l’aide d’une valeur de chaîne de requête (?id=7 ou similaire dans l’URL). En plaçant la valeur d’ID dans un champ masqué, vous pouvez vous assurer qu’elle est disponible lors de l’envoi du formulaire, même si vous n’avez plus accès à l’URL d’origine avec laquelle la page a été appelée.

Contrairement à la page AddMovie , le code de la page EditMovie a deux fonctions distinctes. La première fonction est que lorsque la page est affichée pour la première fois (et seulement ensuite), le code obtient l’ID de film à partir de la chaîne de requête. Le code utilise ensuite l’ID pour lire le film correspondant hors de la base de données et l’afficher (précharger) dans les zones de texte.

La deuxième fonction est que lorsque l’utilisateur clique sur le bouton Envoyer les modifications , le code doit lire les valeurs des zones de texte et les valider. Le code doit également mettre à jour l’élément de base de données avec les nouvelles valeurs. Cette technique est similaire à l’ajout d’un enregistrement, comme vous l’avez vu dans AddMovie.

Ajout de code pour lire un seul film

Pour effectuer la première fonction, ajoutez ce code en haut de la page :

@{
    var title = "";
    var genre = "";
    var year = "";
    var movieId = "";

    if(!IsPost){
        if(!Request.QueryString["ID"].IsEmpty()){
            movieId = Request.QueryString["ID"];
            var db = Database.Open("WebPagesMovies");
            var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
            var row = db.QuerySingle(dbCommand, movieId);
            title = row.Title;
            genre = row.Genre;
            year = row.Year;
        }
        else{
            Validation.AddFormError("No movie was selected.");
        }
    }
}

La majeure partie de ce code se trouve à l’intérieur d’un bloc qui démarre if(!IsPost). L’opérateur ! signifie « pas », de sorte que l’expression signifie si cette demande n’est pas une soumission de post-envoi, ce qui est un moyen indirect de dire si cette requête est la première fois que cette page a été exécutée. Comme indiqué précédemment, ce code ne doit s’exécuter que la première fois que la page s’exécute. Si vous n’avez pas mis le code dans if(!IsPost), il s’exécuterait chaque fois que la page est appelée, que ce soit la première fois ou en réponse à un clic sur un bouton.

Notez que le code inclut un else bloc cette fois. Comme nous l’avons dit lorsque nous avons introduit if des blocs, vous souhaitez parfois exécuter un autre code si la condition que vous testez n’est pas vraie. C’est le cas ici. Si la condition réussit (autrement dit, si l’ID transmis à la page est correct), vous lisez une ligne de la base de données. Toutefois, si la condition ne passe pas, le else bloc s’exécute et le code définit un message d’erreur.

Validation d’une valeur passée à la page

Le code utilise Request.QueryString["id"] pour obtenir l’ID passé à la page. Le code s’assure qu’une valeur a été effectivement passée pour l’ID. Si aucune valeur n’a été passée, le code définit une erreur de validation.

Ce code montre une autre façon de valider les informations. Dans le tutoriel précédent, vous avez travaillé avec l’assistance Validation . Vous avez inscrit des champs pour valider, et ASP.NET effectué automatiquement la validation et affiché des erreurs à l’aide Html.ValidationMessage de et Html.ValidationSummary. Dans ce cas, toutefois, vous ne validez pas vraiment l’entrée utilisateur. Au lieu de cela, vous validez une valeur qui a été passée à la page à partir d’un autre emplacement. L’assistance Validation ne fait pas ça pour vous.

Par conséquent, vous case activée la valeur vous-même, en la testant avec if(!Request.QueryString["ID"].IsEmpty()). En cas de problème, vous pouvez afficher l’erreur à l’aide Html.ValidationSummaryde , comme vous l’avez fait avec l’assistance Validation . Pour ce faire, vous appelez Validation.AddFormError et passez un message à afficher. Validation.AddFormError est une méthode intégrée qui vous permet de définir des messages personnalisés liés au système de validation que vous connaissez déjà. (Plus loin dans ce tutoriel, nous verrons comment rendre ce processus de validation un peu plus robuste.)

Après s’être assuré qu’il existe un ID pour le film, le code lit la base de données, à la recherche d’un seul élément de base de données. (Vous avez probablement remarqué le modèle général pour les opérations de base de données : ouvrir la base de données, définir une instruction SQL et exécuter l’instruction.) Cette fois, l’instruction SQL Select inclut WHERE ID = @0. Étant donné que l’ID est unique, un seul enregistrement peut être retourné.

La requête est effectuée en utilisant db.QuerySingle (et non db.Query, comme vous l’avez utilisé pour la liste des films), et le code place le résultat dans la row variable . Le nom row est arbitraire ; vous pouvez nommer les variables comme vous le souhaitez. Les variables initialisées en haut sont ensuite remplies avec les détails du film afin que ces valeurs puissent être affichées dans les zones de texte.

Test de la page d’édition (jusqu’à présent)

Si vous souhaitez tester votre page, exécutez la page Films maintenant et cliquez sur un lien Modifier en regard d’un film. Vous verrez la page EditMovie avec les détails renseignés pour le film que vous avez sélectionné :

Capture d’écran montrant la page Modifier le film montrant le film à modifier.

Notez que l’URL de la page inclut quelque chose comme ?id=10 (ou un autre nombre). Jusqu’à présent, vous avez testé que les liens Modifier dans la page Vidéo fonctionnent, que votre page lit l’ID à partir de la chaîne de requête et que la requête de base de données pour obtenir un enregistrement vidéo unique fonctionne.

Vous pouvez modifier les informations du film, mais rien ne se produit lorsque vous cliquez sur Envoyer les modifications.

Ajout de code pour mettre à jour le film avec les modifications de l’utilisateur

Dans le fichier EditMovie.cshtml , pour implémenter la deuxième fonction (en enregistrant les modifications), ajoutez le code suivant juste à l’intérieur de l’accolade fermante du @ bloc. (Si vous ne savez pas exactement où placer le code, vous pouvez consulter la liste complète du code pour la page Modifier le film qui apparaît à la fin de ce tutoriel.)

if(IsPost){
    Validation.RequireField("title", "You must enter a title");
    Validation.RequireField("genre", "Genre is required");
    Validation.RequireField("year", "You haven't entered a year");
    Validation.RequireField("movieid", "No movie ID was submitted!");

    title = Request.Form["title"];
    genre = Request.Form["genre"];
    year = Request.Form["year"];
    movieId = Request.Form["movieId"];

    if(Validation.IsValid()){
        var db = Database.Open("WebPagesMovies");
        var updateCommand = "UPDATE Movies SET Title=@0, Genre=@1, Year=@2 WHERE Id=@3";
        db.Execute(updateCommand, title, genre, year, movieId);
        Response.Redirect("~/Movies");
   }
}

Là encore, ce balisage et ce code sont similaires au code dans AddMovie. Le code se trouve dans un if(IsPost) bloc, car ce code s’exécute uniquement lorsque l’utilisateur clique sur le bouton Envoyer les modifications , c’est-à-dire quand (et uniquement quand) le formulaire a été publié. Dans ce cas, vous n’utilisez pas un test comme if(IsPost && Validation.IsValid()), c’est-à-dire que vous ne combinez pas les deux tests à l’aide de AND. Dans cette page, vous déterminez d’abord s’il existe une soumission de formulaire (if(IsPost)), puis vous inscrivez les champs pour validation. Vous pouvez ensuite tester les résultats de validation (if(Validation.IsValid()). Le flux est légèrement différent de celui de la page AddMovie.cshtml , mais l’effet est le même.

Vous obtenez les valeurs des zones de texte à l’aide Request.Form["title"] d’un code similaire pour les autres <input> éléments. Notez que cette fois, le code obtient l’ID du film hors du champ masqué (<input type="hidden">). Lors de la première exécution de la page, le code a obtenu l’ID de la chaîne de requête. Vous obtenez la valeur du champ masqué pour vous assurer que vous obtenez l’ID du film qui a été affiché à l’origine, au cas où la chaîne de requête a été modifiée depuis lors.

La différence vraiment importante entre le code AddMovie et ce code est que dans ce code, vous utilisez l’instruction SQL Update au lieu de l’instruction Insert Into . L’exemple suivant montre la syntaxe de l’instruction SQL Update :

UPDATE table SET col1="value", col2="value", col3="value" ... WHERE ID = value

Vous pouvez spécifier n’importe quelle colonne dans n’importe quel ordre, et vous n’avez pas nécessairement à mettre à jour chaque colonne au cours d’une Update opération. (Vous ne pouvez pas mettre à jour l’ID lui-même, car cela enregistrerait l’enregistrement en tant que nouvel enregistrement, et cela n’est pas autorisé pour une Update opération.)

Notes

Important La Where clause avec l’ID est très importante, car c’est ainsi que la base de données sait quel enregistrement de base de données vous souhaitez mettre à jour. Si vous laissiez la Where clause , la base de données mettrait à jour chaque enregistrement de la base de données. Dans la plupart des cas, ce serait un désastre.

Dans le code, les valeurs à mettre à jour sont passées à l’instruction SQL à l’aide d’espaces réservés. Pour répéter ce que nous avons dit précédemment : pour des raisons de sécurité, utilisez uniquement des espaces réservés pour passer des valeurs à une instruction SQL.

Une fois que le code utilise db.Execute pour exécuter l’instruction Update , il redirige vers la page de référencement, où vous pouvez voir les modifications.

Conseil

Différentes instructions SQL, différentes méthodes

Vous avez peut-être remarqué que vous utilisez des méthodes légèrement différentes pour exécuter différentes instructions SQL. Pour exécuter une Select requête qui retourne potentiellement plusieurs enregistrements, vous utilisez la Query méthode . Pour exécuter une Select requête dont vous savez qu’elle ne retournera qu’un seul élément de base de données, utilisez la QuerySingle méthode . Pour exécuter des commandes qui apportent des modifications, mais qui ne retournent pas d’éléments de base de données, utilisez la Execute méthode .

Vous devez avoir des méthodes différentes, car chacune d’elles retourne des résultats différents, comme vous l’avez déjà vu dans la différence entre Query et QuerySingle. (La Execute méthode retourne également une valeur, à savoir le nombre de lignes de base de données qui ont été affectées par la commande, mais vous l’avez ignorée jusqu’à présent.)

Bien entendu, la Query méthode ne peut retourner qu’une seule ligne de base de données. Toutefois, ASP.NET traite toujours les résultats de la Query méthode comme une collection. Même si la méthode ne retourne qu’une seule ligne, vous devez extraire cette seule ligne de la collection. Par conséquent, dans les situations où vous savez que vous ne récupérerez qu’une seule ligne, il est un peu plus pratique d’utiliser QuerySingle.

Il existe quelques autres méthodes qui effectuent des types spécifiques d’opérations de base de données. Vous trouverez une liste des méthodes de base de données dans la référence rapide de l’API pages Web ASP.NET.

Rendre la validation de l’ID plus robuste

La première fois que la page s’exécute, vous obtenez l’ID du film à partir de la chaîne de requête afin de pouvoir obtenir ce film à partir de la base de données. Vous vous êtes assuré qu’il y avait réellement une valeur à rechercher, ce que vous avez fait à l’aide de ce code :

if(!IsPost){
    if(!Request.QueryString["ID"].IsEmpty()){
        // Etc.
    }
}

Vous avez utilisé ce code pour vous assurer que si un utilisateur accède à la page EditMovies sans sélectionner au préalable un film dans la page Films , la page affiche un message d’erreur convivial. (Sinon, les utilisateurs verraient une erreur qui ne ferait probablement que les confondre.)

Toutefois, cette validation n’est pas très robuste. La page peut également être appelée avec les erreurs suivantes :

  • L’ID n’est pas un nombre. Par exemple, la page peut être appelée avec une URL telle que http://localhost:nnnnn/EditMovie?id=abc.
  • L’ID est un nombre, mais il fait référence à un film qui n’existe pas (par exemple, http://localhost:nnnnn/EditMovie?id=100934).

Si vous êtes curieux de voir les erreurs qui résultent de ces URL, exécutez la page Films . Sélectionnez un film à modifier, puis remplacez l’URL de la page EditMovie par une URL qui contient un ID alphabétique ou l’ID d’un film inexistant.

Alors, que devez-vous faire ? Le premier correctif consiste à vérifier qu’un ID est non seulement passé à la page, mais que l’ID est un entier. Modifiez le code du test pour !IsPost qu’il ressemble à cet exemple :

if(!IsPost){
    if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()) {
       // Etc.

Vous avez ajouté une deuxième condition au IsEmpty test, liée à && (AND logique) :

Request.QueryString["ID"].IsInt()

Dans le didacticiel Introduction à la programmation pages Web ASP.NET, vous pouvez vous rappeler que des méthodes telles AsBool qu’une AsInt chaîne de caractères sont converties en un autre type de données. La IsInt méthode (et d’autres, comme IsBool et IsDateTime) sont similaires. Toutefois, ils testent uniquement si vous pouvez convertir la chaîne, sans effectuer réellement la conversion. Donc ici, vous dites essentiellement si la valeur de la chaîne de requête peut être convertie en entier ....

L’autre problème potentiel est la recherche d’un film qui n’existe pas. Le code pour obtenir un film ressemble à ce code :

var row = db.QuerySingle(dbCommand, movieId);

Si vous passez une movieId valeur à la QuerySingle méthode qui ne correspond pas à une vidéo réelle, rien n’est retourné et les instructions qui suivent (par exemple, title=row.Title) entraînent des erreurs.

Là encore, il y a une solution facile. Si la db.QuerySingle méthode ne retourne aucun résultat, la row variable est null. Vous pouvez donc case activée si la row variable est null avant d’essayer d’en obtenir des valeurs. Le code suivant ajoute un if bloc autour des instructions qui obtiennent les valeurs de l’objet row :

if(row != null) {
    title = row.Title;
    genre = row.Genre;
    year = row.Year;
}
else{
    Validation.AddFormError("No movie was found for that ID.");
}

Avec ces deux tests de validation supplémentaires, la page devient plus à l’épreuve des puces. Le code complet de la !IsPost branche ressemble maintenant à cet exemple :

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

Nous notons une fois de plus que cette tâche est une bonne utilisation pour un else bloc. Si les tests ne réussissent pas, les blocs définissent des else messages d’erreur.

Un dernier détail utile consiste à ajouter un lien vers la page Films . Dans le flux ordinaire des événements, les utilisateurs commencent à la page Films et cliquent sur un lien Modifier . Cela les amène à la page EditMovie , où ils peuvent modifier le film et cliquer sur le bouton. Une fois que le code a traité la modification, il redirige vers la page Films .

Toutefois :

  • L’utilisateur peut décider de ne rien changer.
  • L’utilisateur est peut-être arrivé à cette page sans cliquer d’abord sur un lien Modifier dans la page Films .

Quoi qu’il en soit, vous souhaitez leur permettre de revenir facilement à la liste main. Il s’agit d’une solution simple : ajoutez le balisage suivant juste après la balise fermante </form> dans le balisage :

<p><a href="~/Movies">Return to movie listing</a></p>

Ce balisage utilise la même syntaxe pour un <a> élément que vous avez vu ailleurs. L’URL inclut ~ comme « racine du site web ».

Test du processus de mise à jour du film

Maintenant, vous pouvez tester. Exécutez la page Films , puis cliquez sur Modifier en regard d’un film. Lorsque la page ModifierMovie s’affiche, apportez des modifications au film, puis cliquez sur Envoyer les modifications. Lorsque la liste de films s’affiche, assurez-vous que vos modifications sont affichées.

Pour vous assurer que la validation fonctionne, cliquez sur Modifier pour un autre film. Lorsque vous accédez à la page EditMovie , désactivez le champ Genre (ou Champ Année , ou les deux) et essayez d’envoyer vos modifications. Vous verrez une erreur, comme vous vous y attendiez :

Page Modifier le film montrant les erreurs de validation

Cliquez sur le lien Retour à la liste des films pour abandonner vos modifications et revenir à la page Films .

À venir

Dans le tutoriel suivant, vous allez voir comment supprimer un enregistrement vidéo.

@{
    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")
                )
            )
        </div>
    <p>
        <a href="~/AddMovie">Add a movie</a>
    </p>
    </body>
</html>

Liste complète de la page pour modifier la page vidéo

@{
    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 selected.");
            }
        }
        else{
            Validation.AddFormError("No movie was selected.");
        }
    }

    if(IsPost){
        Validation.RequireField("title", "You must enter a title");
        Validation.RequireField("genre", "Genre is required");
        Validation.RequireField("year", "You haven't entered a year");
        Validation.RequireField("movieid", "No movie ID was submitted!");

        title = Request.Form["title"];
        genre = Request.Form["genre"];
        year = Request.Form["year"];
        movieId = Request.Form["movieId"];

        if(Validation.IsValid()){
            var db = Database.Open("WebPagesMovies");
            var updateCommand = "UPDATE Movies SET Title=@0, Genre=@1, Year=@2 WHERE Id=@3";
            db.Execute(updateCommand, title, genre, year, movieId);
            Response.Redirect("~/Movies");
        }
    }
}

<!DOCTYPE html>
<html>
  <head>
   <meta charset="utf-8" />
   <title>Edit a Movie</title>
    <style>
      .validation-summary-errors{
        border:2px dashed red;
        color:red;
        font-weight:bold;
        margin:12px;
      }
    </style>
  </head>
  <body>
    <h1>Edit a Movie</h1>
      @Html.ValidationSummary()
      <form method="post">
      <fieldset>
        <legend>Movie Information</legend>

        <p><label for="title">Title:</label>
           <input type="text" name="title" value="@title" /></p>

        <p><label for="genre">Genre:</label>
           <input type="text" name="genre" value="@genre" /></p>

        <p><label for="year">Year:</label>
           <input type="text" name="year" value="@year" /></p>

        <input type="hidden" name="movieid" value="@movieId" />

        <p><input type="submit" name="buttonSubmit" value="Submit Changes" /></p>
      </fieldset>
    </form>
    <p><a href="~/Movies">Return to movie listing</a></p>
  </body>
</html>

Ressources supplémentaires