PRESENTATION D'ASP.NET WEB PAGES

Mise à jour des données

Ce tutoriel vous montre comment mettre à jour (changer) les données d'une base de données lorsque vous utilisez ASP.NET Web Pages (Razor).

8 commentaires Donner une note  l'article (5)

Article lu   fois.

Les deux auteur et traducteur

Traducteur : Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Préface

Ce tutoriel vous montre comment mettre à jour (changer) les données d'une base de données lorsque vous utilisez ASP.NET Web Pages (Razor). Cela suppose que vous avez étudié ASP.NET Web Page — Saisie de données avec un formulaire.

Note de la rédaction Développez.com :

Ce tutoriel est basé sur la technologie ASP.NET Web Page. Si elle est toujours d’actualité et peut continuer d’être utilisée sans aucun soucis pour des projets existants, Microsoft recommande l’usage d’ASP.NET Core Razor Page pour de nouveaux projets.

De plus, ce tutoriel est basé sur l’utilisation de WebMatrix comme environnement de développement. Aujourd’hui, cet environnement est considéré comme obsolète et il est préférable d’utiliser un environnement de développement récent comme Visual Studio ou Visual Studio Code. Néanmoins, cela ne devrait pas gêner la lecture de ce tutoriel.

Précision vis à vis de la version anglaise : les liens invalides ont été retirés de la traduction.

I-A. Qu'allez-vous apprendre ?

  • comment sélectionner un enregistrement unique dans le WebGrid helper ;
  • comment lire une ligne dans la base de données ;
  • comment précharger un formulaire avec les valeurs d'une ligne de la base de données ;
  • comment mettre à jour une ligne existante de la base de données ;
  • comment stocker l'information dans la page sans l'afficher ;
  • comment utiliser un champ caché pour stocker l'information.

I-B. Fonctionnalités/technologie abordées :

  • le WebGrid helper ;
  • la commande SQL Update ;
  • la méthode Database.Execute ;
  • les champs cachés (<input type=« hidden »>).

II. Qu'allez-vous construire ?

Dans le tutoriel précédent, vous avez appris comment ajouter de nouvelles lignes à la base de données. Ici, vous allez apprendre comment afficher une ligne pour la modifier. Dans la page Movies, vous allez mettre à jour le WebGrid helper afin qu'il affiche un lien Edit pour chaque film :

Image non disponible

Lorsque vous cliquez sur le lien Edit, il vous présente une page différente, où les informations du film sont déjà présentes dans le formulaire :

Image non disponible

Vous pouvez changer n'importe quelle valeur. Lorsque vous soumettez les modifications, le code de la page met à jour la base de données et vous renvoie vers 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, aussi une bonne partie de ce tutoriel vous sera familier.

Il existe plusieurs façons de procéder pour implémenter la modification d'un film. L'approche présentée a été choisie parce qu'elle est facile à mettre en œuvre et à comprendre.

III. Ajouter un lien d'édition (Edit Link) à la liste de films

Pour commencer, vous devez mettre à jour la page Movies afin que chaque ligne de film de la liste contienne un lien Edit.

Ouvrez le fichier Movies.cshtml.

Dans le corps de la page, changez le balisage du WebGrid en ajoutant une colonne. Ici le balisage modifié :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
@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")
    )
)

Voici la nouvelle colonne :

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

Le but de cette colonne est de montrer un lien (élément <a>) dont le texte marque « Edit ». Ensuite nous devons créer un lien qui ressemble à ce qui suit lorsque la page s'exécute, avec une valeur d'id différente pour chaque film :

 
Sélectionnez
http://localhost:43097/EditMovie?id=7

Ce lien invoque une page nommée EditMovie et il lui passe la chaîne de requête ?id=7.

La syntaxe de la nouvelle colonne peut sembler un peu complexe, mais c'est seulement parce cela regroupe plusieurs éléments. Chaque élément pris individuellement est simple. Si vous vous concentrez juste sur l'élément <a>, vous voyez ce balisage :

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

Regardons comment la grille fonctionne. Elle affiche les lignes, une pour chaque enregistrement de la base de données. Elle affiche une colonne pour chaque champ des enregistrements de la base de données. Pendant la construction de chaque ligne de la grille, l'item de l'objet contient l'enregistrement de la base de données (item) pour cette ligne. Cet agencement vous donne un moyen dans le code pour prélever les données de cette ligne. C'est ce que vous voyez ici : l'expression item.ID prélève la valeur de l'élément courant de la base de données. Vous pouvez obtenir chacune des valeurs de la base de données (title, genre, ou year) de la même manière en utilisant item.Title, item.Genre, ou item.Year.

 
Sélectionnez
href="/EditMovie?id=2"

Naturellement la véritable valeur de l'id sera différente pour chaque ligne.

IV. Création d'un affichage personnalisé pour la colonne de la grille

Maintenant revenons aux colonnes de la grille. A l'origine vous avez ajouté trois colonnes dans la grille pour afficher seulement des valeurs de données (title, genre et year). Vous spécifiez cet affichage en passant le nom de la colonne — par exemple, grid.column(« Title »).

La nouvelle colonne de lien Edit est différente. Au lieu de spécifier un nom de colonne, vous passez un paramètre de format. Ce paramètre vous permet de définir le balisage que le WebGrid helper restituera avec la valeur de l'item pour afficher la colonne en gras ou en vert ou avec n'importe quel format que vous souhaitez. Par exemple, si vous souhaitez que le titre apparaisse en gras, vous pouvez créer une colonne comme dans cet exemple :

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

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

Une fois que vous connaissez la propriété format, c'est simple de comprendre comment la nouvelle colonne de liens Edit est intégrée :

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

La colonne se compose uniquement du balisage qui restitue le lien, ainsi que de la donnée (l'ID) qui est extraite de la ligne issue de la base de données.

IV-A. Paramètres nommés et paramètres positionnés pour une méthode

De nombreuses fois, lorsque vous appelez une méthode et lui passez des paramètres, vous avez simplement écrit les valeurs des paramètres séparées par des virgules. Comme dans ces deux exemples :

 
Sélectionnez
1.
2.
3.
db.Execute(insertCommand, title, genre, year)

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

Nous n'avons pas abordé la question lorsque lorsque vous avez vu ce code la première fois. Mais dans chaque cas, vous avez passé les paramètres dans un ordre précis à la méthode, à savoir, l'ordre dans lequel ces paramètres sont définis dans celle-ci. Pour db.Execute et Validation.RequireFields, si vous mélangez l'ordre des valeurs que vous passez, vous obtiendrez un message d'erreur lorsque la page s'exécutera, ou tout du moins des résultats étranges. Clairement, vous devez connaître l'ordre de passage des paramètres (dans WebMatrix, l'Intellisense peut vous aider à apprendre et comprendre le nom, le type et l'ordre des paramètres).

Comme alternative au passage des valeurs dans l'ordre, vous pouvez utiliser les paramètres nommés (le passage de paramètres dans l'ordre est connu comme étant l'utilisation de paramètres positionnés). Pour les paramètres nommés, vous incluez explicitement le nom du paramètre lorsque vous passez la valeur. Vous utiliserez les paramètres nommés de nombreuses fois dans ce tutoriel. Par exemple :

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

Et

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@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 pratiques dans deux situations, spécialement lorsque une méthode possède de nombreux paramètres. L'une d'elles est lorsque vous voulez passer seulement un ou deux paramètres, mais que ces valeurs ne sont pas en première position dans la liste des paramètres. L'autre situation est lorsque vous voulez améliorer la lisibilité de votre code en passant les paramètres dans un ordre qui a plus de sens pour vous.

Évidemment, pour utiliser les paramètres nommés, vous devez connaître leur nom. L'Intellisense de WebMatrix peut vous montrer ces noms, mais il ne peut pas les placer pour vous.

V. Création de la page Edit

Maintenant vous pouvez créer la page EditMovie. Lorsque les utilisateurs cliquent sur le lien Edit, ils se retrouvent sur cette page.

Créez une page nommée EditMovie.cshtml et remplacez son contenu avec le balisage suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
<!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>
</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 à ce que vous avez dans la page AddMovie. Il y a une petite différence dans le texte pour le bouton soumettre. Comme avec la page AddMovie, il y a un appel à Html.ValidationSummary qui affichera les erreurs de validation s'il y en a. Cette fois nous omettons les appels à Validation.Message, puisque les erreurs s'afficheront dans le sommaire de validation.

Notez de nouveau que l'attribut de method de l'élément <form> est positionné sur post. Comme avec la page AddMovie.cshtml, cette page enregistre les modifications dans la base de données. Par conséquent, ce formulaire doit effectuer une opération POST (pour plus d'informations sur les différences entre les opérations GET et POST, regardez la sidebar dans le chapitre Sécurité des verbes HTTP, GET, POST sur HTML forms).

Comme vous avez vu dans un tutoriel précédent, les attributs value des zones de texte sont placés avec le code Razor dans l'ordre pour les précharger. Cette fois, cependant, vous utilisez des variables telles que title et genre pour cette tâche à la place de Request.Form[« title »] :

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

Comme avant, ce balisage préchargera les valeurs des zones de texte avec les valeurs du film. Vous verrez dans un moment pourquoi cette fois il est pratique d'utiliser les variables plutôt que l'objet Request.

Il y a aussi l'élément <input type=« hidden »> 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 en utilisant une valeur de chaîne de requête (?id=7 ou quelque chose de similaire dans l'URL). En plaçant la valeur de l'ID dans un champ caché, vous pouvez être sûr de sa disponibilité lorsque le formulaire est soumis, même si vous n'avez plus accès à l'URL d'origine avec laquelle la page avait été appelée.

Contrairement à la page AddMovie, le code de la page EditMovie a deux fonctions distinctes. La première est lorsque la page est affichée pour la première fois (et seulement dans ce cas), le code prend l'ID du film dans la chaîne de requête. Il utilise ensuite cet ID pour lire le film correspondant dans la base de données et l'afficher (précharger) dans les zones de texte.

La seconde fonction est lorsque l'utilisateur clique le bouton Submit Changes, le code va lire les valeurs des zones de texte et les valide. Le code va aussi mettre à jour la ligne de la base de données avec les nouvelles valeurs. Cette technique est similaire à l'ajout d'enregistrement, comme vous avez vu dans AddMovie.

VI. Ajout du code pour lire un film

Pour réaliser la première fonction, ajouter ce code en haut de la page :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
@{
    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 plupart du code est inclus dans le bloc if(!IsPost). L'opérateur ! signifie « not », aussi cette expression signifie « si la demande n'est pas soumise par post », laquelle est une façon indirecte de dire « si c'est la première fois que la page s'exécute avec cette demande ». Comme indiqué précédemment, ce code fonctionnera seulement à la première exécution de la page. Si vous omettez le morceau de code if(!IsPost), cela serait exécuté à chaque appel de la page, la première fois et aussi en réponse à un clic sur un bouton.

Notez que cette fois, le code inclut un bloc Else. Comme nous l'avons dit lorsque nous avons étudié les blocs if, parfois vous voulez exécuter un autre code si la condition testée n'est pas vraie. C'est le cas ici. Si la condition est ok (ce qui est le cas si l'ID passé à la page est correct), vous lisez une ligne de la base de données. Cependant, si la condition est incorrecte, le bloc Else s'exécute et le code définit un message d'erreur.

VII. Validation d'une valeur passée à la page

Le code utilise Request.QueryString[« id »] pour obtenir l'ID passé à la page. Le code vérifie qu'une valeur est effectivement passée à l'ID. Si aucune valeur n'est passée, le code définit une erreur de validation.

Ce code montre une façon différente de valider une information. Dans le tutoriel précédent, vous avez travaillé avec Validation helper. Vous référenciez les champs à valider et ASP.NET appliquait automatiquement la validation et affichait les erreurs en utilisant Html.ValidationMessage et Html.ValidationSummary. Cependant, dans ce cas, vous n'êtes pas en train de valider les saisies utilisateur. Vous validez une valeur passée à la page par un autre moyen. Le Validation helper ne peut pas gérer cela pour vous.

Par conséquent, vous vérifiez la valeur vous même en testant avec if(!Request.QueryString[« ID »].IsEmpty()). S'il y a un problème, vous pouvez afficher l'erreur avec Html.ValidationSummary, comme vous l’auriez fait avec Validation helper. Pour faire cela, vous appelez Validation.AddFormError en lui donnant le message à afficher. Validation.AddFormError est une méthode intégrée qui vous permet de définir des messages personnalisés qui seront reliés avec le système de validation auquel vous êtes familiarisé (plus tard dans ce tutoriel nous aborderons comment rendre ce processus de validation un peu plus robuste).

Après s'être assuré qu'il y a un ID pour le film, le code lit dans la base de données à la recherche d'un élément unique (vous avez probablement remarqué le pattern général pour une opération sur la base de données : ouverture de la base de données, définition de l'instruction SQL et exécution de celle-ci). Cette fois, l'instruction SQL Select inclut WHERE ID = @0. Puisque l'ID est unique, seul un enregistrement peut être renvoyé.

La requête est effectuée en utilisant db.QuerySingle (pas db.Query, que vous avez utilisé dans la liste de films) et le code place le résultat dans une variable row. Le nom row est arbitraire ; vous pouvez nommer cette variable comme bon vous semble. Les variables définies en haut sont remplies avec les détails du film, ainsi ces valeurs peuvent être affichées dans les zones de texte.

VIII. Test de la page Edit

Si vous souhaitez tester votre page, exécutez la page Movie maintenant et cliquez sur un des liens Edit présents à coté de chaque film. Vous voyez la page EditMovie avec les détails renseignés pour le film que vous avez sélectionné :

Image non disponible

Remarquez 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 Edit dans la page Movie fonctionnent et aussi que votre page lit l'Id dans la chaîne de requête et interroge la base de données pour obtenir un enregistrement unique d'un film.

Vous pouvez modifier les informations du film, mais rien ne se passe lorsque vous cliquez Submit Changes.

IX. Ajout du code pour mettre à jour le film avec les modifications des utilisateurs

Dans le fichier EditMovie.cshtml, pour implémenter la deuxième fonctionnalité (sauvegarder les changements), ajoutez le code suivant juste à l'intérieur de l'accolade fermante du bloc @ Si vous n'êtes pas sur de l'endroit exact où vous devez placer le code, vous pouvez regarder « Listing complet de la page MovieListing complet pour la page EditMovie (mis à jour avec les liens Edit) » à la fin du tutoriel.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
    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");
       }
    }

De nouveau, ce balisage et ce code sont similaires au code de AddMovie. Le code est dans un bloc if(IsPost) parce qu'il s'exécute seulement lorsque l'utilisateur clique sur le bouton Submit Changes — c'est-à-dire lorsque (et seulement lorsque) le formulaire a été posté. 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 en utilisant AND. Dans cette page, vous déterminez d'abord si ce formulaire a été soumis (if(IsPost)) et ensuite seulement, vous référencez les champs pour la validation. Le déroulement 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 en utilisant Request.Form[« title »] et un code similaire pour les autres éléments <input>. Remarquez que cette fois, le code obtient l'ID du film du champ caché (<input type=« hidden »>). Lorsque la page s'exécute la première fois, le code a obtenu l'ID de la chaîne de requête dans l'URL. Vous prélevez la valeur du champ caché afin d'être sur que vous obtenez l'ID du film affiché à l'origine, au cas où la chaîne de requête aurait été modifiée depuis d'une manière ou d'une autre.

La différence réellement importante entre le code de AddMovie et ce code est qu'ici vous utilisez l'instruction SQL Update à la place de l'instruction Insert Into. L'exemple suivant vous montre la syntaxe de l'instruction Update.

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

Vous pouvez spécifier chaque colonne dans n'importe quel ordre, et vous n'avez pas à mettre à jour toutes les colonnes pendant une opération Update (vous ne pouvez pas mettre à jour l'ID parce que ce serait enregistrer la ligne comme une nouvelle ligne et ce n'est pas permis pour une opération Update).

Important : la clause Where avec l'ID est très importante, c'est ainsi que la base de données détermine quel enregistrement est à mettre à jour. Si vous omettez la clause Where, la base de données mettra à jour toutes les lignes. Dans la plupart des cas, c'est un désastre.

Dans le code, les valeurs à mettre à jour sont passées à l'instruction SQL par l'utilisation de paramètres. Pour reprendre ce que nous avons dit avant : pour des raisons de sécurité, il faut seulement utiliser les paramètres pour passer des valeurs à une instruction SQL.

Ensuite le code utilise db.Execute pour exécuter l'instruction Update. Il redirige vers la page liste, où vous pouvez voir les modifications.

IX-A. Instructions SQL différentes, méthodes différentes

Vous avez probablement remarqué que vous utilisez des méthodes sensiblement différentes pour exécuter les diverses instructions SQL. Pour exécuter une requête Select qui peut potentiellement renvoyer plusieurs lignes, vous utilisez la méthode Query. Pour exécuter une requête Select dont vous savez qu'elle vous renverra un seul élément, vous utilisez la méthode QuerySingle. Pour exécuter une commande qui effectue des changements mais ne retourne aucun élément, vous utilisez la méthode Execute.

Vous avez différentes méthodes parce que chacune d'elles vous renvoie des résultats différents, comme vous avez pu voir la différence entre Query et QuerySingle (en réalité, la méthode Execute renvoie aussi une valeur — à savoir, le nombre de lignes affectées par la commande — mais vous pouvez ignorer cela).

Évidemment, la méthode Query peut renvoyer seulement une ligne. Cependant, ASP.NET traite toujours le résultat de la méthode Query comme une collection. Même si la méthode ne renvoie qu'une ligne, vous devez extraire cette ligne unique de la collection. Cependant, en situation lorsque vous savez que vous récupérez qu'une seule ligne, il est plus pratique d'utiliser QuerySingle.

Il y a quelques autres méthodes qui réalisent des opérations de base de données de types spécifiques. Vous pouvez trouver une liste de ces méthodes dans ASP.NET Web Pages API Quick Reference.

X. Effectuer une validation de l'ID plus robuste

A la première exécution de la page, vous obtenez l'ID du film depuis la chaîne de requête de l'URL de sorte que vous pouvez obtenir le film dans la base de données. Vous pouvez vous assurer qu'il y a une valeur pour la recherche en utilisant ce code :

 
Sélectionnez
1.
2.
3.
4.
5.
if(!IsPost){
    if(!Request.QueryString["ID"].IsEmpty()){
        // Etc.
    }
}

Vous avez utilisé ce code afin d'être sûr que si un utilisateur arrive dans la page EditMovies sans avoir sélectionné un film dans la page Movies, un message d'erreur convivial sera affiché. Autrement les utilisateurs verront une erreur qui pourrait probablement les embrouiller.

Cependant, cette validation n'est pas très robuste. La page peut aussi être appelée avec ces erreurs :

  • l'ID n'est pas un nombre. Par exemple, la page peut être appelée avec une URL comme http://localhost:nnnnn/EditMovie?id=abc;
  • l'ID est un nombre, mais il 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 résultantes de ces URL, exécutez la page Movies. Sélectionnez un film à éditer et puis changez l'URL de la page EditMovie avec une URL qui contient un ID alphabétique ou un ID de film inexistant.

Alors que devez vous faire ? La première solution est de faire en sorte que non seulement un ID soit passé à la page, mais qu'il soit un un entier. Changez le code du test !IsPost pour qu'il ressemble à cet exemple :

 
Sélectionnez
1.
2.
3.
if(!IsPost){
    if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()) {
       // Etc.

Vous avez ajouté une deuxième condition au test IsEmpty, lié avec && (ET logique) :

 
Sélectionnez
Request.QueryString["ID"].IsInt()

Vous devez vous souvenir du tutoriel <Introduction to ASP.NET Web Pages Programming> <> que des méthodes comme AsBool et AsInt qui convertissent un caractère dans un autre type de données. La méthode IsInt (et d'autres, comme IsBool et IsDateTime) est similaire. Cependant, IsInt teste seulement si vous pouvez convertir la chaîne, sans réellement effectuer la conversion. Ici vous pouvez vous dire si la chaîne de requête peut être convertie en entier … .

L'autre problème potentiel est la recherche d'un film inexistant. Le code pour obtenir un film ressemble à ceci :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
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 nouveaux tests de validation, la page devient plus robuste. Le code complet de la branche !IsPost ressemble maintenant à cet exemple :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
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 remarquons encore une fois que ces tests sont d'un bon usage pour le bloc Else. Si les tests ne passent pas, les blocs Else définissent les messages d'erreurs.

XI. Ajout d'un lien pour revenir à la page Movies

Un dernier détail est d'ajouter un lien de retour sur la page Movies. Dans un flot d'utilisation classique, les utilisateurs démarrent sur la page Movies et cliquent sur le lien Edit. Cela les amène sur la page EditMovie où ils peuvent modifier le film et cliquer sur le bouton. Ensuite le code procède aux modifications et redirige vers la page Movies.

Cependant :

  • l'utilisateur peut décider de ne rien changer ;
  • l'utilisateur peut arriver sur cette page sans avoir cliqué sur un lien Edit de la page Movies.

Quoi qu'il en soit, vous souhaitez qu'il puisse facilement revenir à la liste principale. C'est facilement faisable — ajoutez ce balisage juste après la balise de fermeture <Form> dans le balisage :

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

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

XII. Test du processus de mise à jour d'un film

Maintenant vous pouvez tester. Exécutez la page Movies, et cliquez sur Edit à coté d'un film. Lorsque la page EditMovie apparaît, modifiez le film et cliquez sur Submit Changes. Lorsque la liste de films s'affiche, vérifiez que vos modifications sont présentes.

Afin de vérifier que la validation fonctionne, cliquez sur Edit pour un autre film. Lorsque vous êtes sur la page EditMovie, effacez le champ Genre (ou Year, ou les deux) et essayez de soumettre les changements. Vous verrez une erreur s’afficher comme vous le souhaitez :

Image non disponible

Cliquez sur le lien Return to movie listing pour abandonner vos modifications et revenir à la page Movies.

XIII. Prochainement

Dans le prochain tutoriel, vous verrez comment supprimer un enregistrement de film.

XIV. Listing complet de la page EditMovie (mis à jour avec les liens Edit)

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
@{
    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>

XV. Listing complet pour la page EditMovie

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
@{
    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>
</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>

XVI. Ressources supplémentaires

XVII. Information sur les auteurs

Tom FitzMacken — Tom FitzMacken est un auteur senior dans la programmation de l'équipe suivi du contenu sur la plateforme Web et Outils.

XVIII. Postface

XVIII-A. Remerciements

Nous remercions François DORIN pour la relecture et la validation technique et escartefigue pour la relecture orthographique.

XVIII-B. Sources

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2019 Hervé Taraveau. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.