Partager via


Utiliser des contrôleurs et des vues pour implémenter une interface utilisateur liste/détails

par Microsoft

Télécharger le PDF

Il s’agit de l’étape 4 d’un tutoriel gratuit sur l’application « NerdDinner » qui explique comment créer une application web petite mais complète à l’aide de ASP.NET MVC 1.

L’étape 4 montre comment ajouter un contrôleur à l’application qui tire parti de notre modèle pour fournir aux utilisateurs une expérience de navigation de liste/détails des données pour les dîners sur notre site NerdDinner.

Si vous utilisez ASP.NET MVC 3, nous vous recommandons de suivre les didacticiels Prise en main Avec MVC 3 ou MVC Music Store.

Étape 4 de NerdDinner : contrôleurs et vues

Avec les frameworks web traditionnels (ASP, PHP, ASP.NET Web Forms classiques), les URL entrantes sont généralement mappées aux fichiers sur le disque. Par exemple : une demande d’URL comme « /Products.aspx » ou « /Products.php » peut être traitée par un fichier « Products.aspx » ou « Products.php ».

Les frameworks MVC basés sur le web mappent les URL au code du serveur d’une manière légèrement différente. Au lieu de mapper les URL entrantes aux fichiers, elles mappent plutôt les URL aux méthodes des classes. Ces classes sont appelées « Contrôleurs » et sont responsables du traitement des requêtes HTTP entrantes, de la gestion des entrées utilisateur, de la récupération et de l’enregistrement des données, et de la détermination de la réponse à renvoyer au client (affichage HTML, téléchargement d’un fichier, redirection vers une autre URL, etc.).

Maintenant que nous avons créé un modèle de base pour notre application NerdDinner, notre prochaine étape sera d’ajouter un contrôleur à l’application qui en tire parti pour fournir aux utilisateurs une expérience de navigation de liste/détails des données pour les dîners sur notre site.

Ajout d’un contrôleur DinnersController

Nous allons commencer par cliquer avec le bouton droit sur le dossier « Contrôleurs » dans notre projet web, puis sélectionner la commande de menu Add-Controller> (vous pouvez également exécuter cette commande en tapant Ctrl-M, Ctrl-C) :

Capture d’écran de la fenêtre Explorateur de solutions montrant le dossier Contrôleurs et les éléments de menu Ajouter et contrôleur mis en évidence en bleu.

La boîte de dialogue « Ajouter un contrôleur » s’affiche :

Capture d’écran de la boîte de dialogue Ajouter un contrôleur montrant le champ Nom du contrôleur rempli avec le texte Dinners Controller.

Nous allons nommer le nouveau contrôleur « DinnersController », puis cliquer sur le bouton « Ajouter ». Visual Studio ajoute ensuite un fichier DinnersController.cs sous notre répertoire \Controllers :

Capture d’écran de la fenêtre Explorateur de solutions montrant le fichier Dinner Controllers point c s mis en évidence en bleu.

Il ouvre également la nouvelle classe DinnersController dans l’éditeur de code.

Ajout de méthodes d’action Index() et Details() à la classe DinnersController

Nous voulons permettre aux visiteurs à l’aide de notre application de parcourir une liste des prochains dîners, et leur permettre de cliquer sur n’importe quel dîner dans la liste pour voir des détails spécifiques à ce sujet. Pour ce faire, nous publierons les URL suivantes à partir de notre application :

URL Objectif
/Dîners/ Afficher une liste HTML des prochains dîners
/Dinners/Details/[id] Affichez les détails d’un dîner spécifique indiqué par un paramètre « id » incorporé dans l’URL, qui correspondra à l’ID dîner du dîner dans la base de données. Par exemple : /Dinners/Details/2 affiche une page HTML avec des détails sur le dîner dont la valeur DinnerID est 2.

Nous publierons les implémentations initiales de ces URL en ajoutant deux « méthodes d’action » publiques à notre classe DinnersController comme ci-dessous :

public class DinnersController : Controller {

    //
    // HTTP-GET: /Dinners/

    public void Index() {
        Response.Write("<h1>Coming Soon: Dinners</h1>");
    }

    //
    // HTTP-GET: /Dinners/Details/2

    public void Details(int id) {
        Response.Write("<h1>Details DinnerID: " + id + "</h1>");
    }
}

Nous allons ensuite exécuter l’application NerdDinner et utiliser notre navigateur pour les appeler. La saisie de l’URL « /Dinners/ » entraîne l’exécution de notre méthode Index() et renvoie la réponse suivante :

Capture d’écran de la fenêtre de réponse générée à partir de l’exécution de l’application NerdDinner, montrant le texte Coming Soon: Dinners.

La saisie de l’URL « /Dinners/Details/2 » entraîne l’exécution de notre méthode Details() et renvoie la réponse suivante :

Capture d’écran de la fenêtre de réponse générée à partir de l’exécution de l’application NerdDinner, montrant le texte Details Dinner I D: 2.

Vous vous demandez peut-être comment ASP.NET MVC a-t-il su créer notre classe DinnersController et appeler ces méthodes ? Pour comprendre cela, examinons rapidement le fonctionnement du routage.

Présentation du routage MVC ASP.NET

ASP.NET MVC inclut un puissant moteur de routage d’URL qui offre une grande flexibilité dans le contrôle de la façon dont les URL sont mappées aux classes de contrôleur. Il nous permet de personnaliser complètement la façon dont ASP.NET MVC choisit la classe de contrôleur à créer, la méthode à appeler sur celle-ci, ainsi que de configurer différentes façons d’analyser automatiquement les variables à partir de l’URL/Querystring et de passer à la méthode en tant qu’arguments de paramètre. Il offre la flexibilité nécessaire pour optimiser totalement un site pour le RÉFÉRENCEMENT (optimisation des moteurs de recherche) et de publier n’importe quelle structure d’URL souhaitée à partir d’une application.

Par défaut, les nouveaux ASP.NET projets MVC sont fournis avec un ensemble préconfiguré de règles de routage d’URL déjà inscrites. Cela nous permet de démarrer facilement sur une application sans avoir à configurer explicitement quoi que ce soit. Les inscriptions de règle de routage par défaut se trouvent dans la classe « Application » de nos projets, que nous pouvons ouvrir en double-cliquant sur le fichier « Global.asax » à la racine de notre projet :

Capture d’écran de la fenêtre Explorateur de solutions montrant le fichier Point global a s a x mis en évidence en bleu et cerclé en rouge.

Les règles de routage MVC par défaut ASP.NET sont inscrites dans la méthode « RegisterRoutes » de cette classe :

public void RegisterRoutes(RouteCollection routes) {

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default",                                       // Route name
        "{controller}/{action}/{id}",                    // URL w/ params
        new { controller="Home", action="Index",id="" }  // Param defaults
    );
}

Les « routes. L’appel de méthode MapRoute() » ci-dessus inscrit une règle de routage par défaut qui mappe les URL entrantes aux classes de contrôleur au format d’URL : « /{controller}/{action}/{id} » : où « controller » est le nom de la classe de contrôleur à instancier, « action » est le nom d’une méthode publique à appeler sur celle-ci et « id » est un paramètre facultatif incorporé dans l’URL qui peut être passé en tant qu’argument à la méthode. Le troisième paramètre passé à l’appel de méthode « MapRoute() » est un ensemble de valeurs par défaut à utiliser pour les valeurs contrôleur/action/id dans le cas où elles ne sont pas présentes dans l’URL (Controller = « Home », Action="Index », Id= »).

Vous trouverez ci-dessous un tableau qui montre comment diverses URL sont mappées à l’aide de la règle d’itinéraire par défaut « /{controllers}/{action}/{id} » :

URL Classe de contrôleur Méthode d'action Paramètres passés
/Dinners/Details/2 DînersController Détails(id) id=2
/Dinners/Edit/5 DînersController Edit(id) id=5
/Dinners/Create DînersController Create() N/A
/Dîners DînersController Index() N/A
/Accueil HomeController Index() N/A
/ HomeController Index() N/A

Les trois dernières lignes indiquent les valeurs par défaut (Controller = Home, Action = Index, Id = «  ») utilisées. Étant donné que la méthode « Index » est inscrite comme nom d’action par défaut s’il n’en est pas spécifié, les URL « /Dinners » et « /Home » entraînent l’appel de la méthode d’action Index() sur leurs classes de contrôleur. Étant donné que le contrôleur « Accueil » est inscrit en tant que contrôleur par défaut s’il n’en est pas spécifié, l’URL « / » entraîne la création du HomeController et l’appel de la méthode d’action Index() sur celui-ci.

Si vous n’aimez pas ces règles de routage d’URL par défaut, la bonne nouvelle est qu’elles sont faciles à modifier : modifiez-les simplement dans la méthode RegisterRoutes ci-dessus. Toutefois, pour notre application NerdDinner, nous n’allons pas modifier les règles de routage d’URL par défaut. Nous allons simplement les utiliser telles quelles.

Utilisation du DinnerRepository de notre DinnersController

Nous allons maintenant remplacer notre implémentation actuelle des méthodes d’action Index() et Details() de DinnersController par des implémentations qui utilisent notre modèle.

Nous allons utiliser la classe DinnerRepository que nous avons créée précédemment pour implémenter le comportement. Nous allons commencer par ajouter une instruction « using » qui fait référence à l’espace de noms « NerdDinner.Models », puis déclarer une instance de notre DinnerRepository en tant que champ sur notre classe DinnerController.

Plus loin dans ce chapitre, nous allons introduire le concept d'« injection de dépendances » et montrer une autre façon pour nos contrôleurs d’obtenir une référence à un DinnerRepository qui permet de meilleurs tests unitaires , mais pour l’instant, nous allons simplement créer une instance de notre DinnerRepository inline comme ci-dessous.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NerdDinner.Models;

namespace NerdDinner.Controllers {

    public class DinnersController : Controller {

        DinnerRepository dinnerRepository = new DinnerRepository();

        //
        // GET: /Dinners/

        public void Index() {
            var dinners = dinnerRepository.FindUpcomingDinners().ToList();
        }

        //
        // GET: /Dinners/Details/2

        public void Details(int id) {
            Dinner dinner = dinnerRepository.GetDinner(id);
        }
    }
}

Nous sommes maintenant prêts à générer une réponse HTML à l’aide de nos objets de modèle de données récupérés.

Utilisation des vues avec notre contrôleur

Bien qu’il soit possible d’écrire du code dans nos méthodes d’action pour assembler du code HTML, puis d’utiliser la méthode d’assistance Response.Write() pour le renvoyer au client, cette approche devient rapidement assez difficile. Une bien meilleure approche consiste à effectuer uniquement une logique d’application et de données à l’intérieur de nos méthodes d’action DinnersController, puis à transmettre les données nécessaires pour afficher une réponse HTML à un modèle de « vue » distinct qui est responsable de la sortie de la représentation HTML de celle-ci. Comme nous le verrons dans un instant, un modèle « affichage » est un fichier texte qui contient généralement une combinaison de balisage HTML et de code de rendu incorporé.

La séparation de notre logique de contrôleur de notre rendu de vue apporte plusieurs avantages majeurs. En particulier, il permet d’appliquer une « séparation claire des préoccupations » entre le code de l’application et le code de mise en forme/rendu de l’interface utilisateur. Cela facilite considérablement le test unitaire de la logique d’application à l’isolement de la logique de rendu de l’interface utilisateur. Il facilite la modification ultérieure des modèles de rendu de l’interface utilisateur sans avoir à apporter de modifications au code d’application. Et cela peut faciliter la collaboration des développeurs et des concepteurs sur des projets.

Nous pouvons mettre à jour notre classe DinnersController pour indiquer que nous voulons utiliser un modèle d’affichage pour renvoyer une réponse d’interface utilisateur HTML en modifiant les signatures de méthode de nos deux méthodes d’action d’avoir un type de retour « void » à avoir un type de retour « ActionResult ». Nous pouvons ensuite appeler la méthode d’assistance View() sur la classe de base controller pour renvoyer un objet « ViewResult » comme ci-dessous :

public class DinnersController : Controller {

    DinnerRepository dinnerRepository = new DinnerRepository();

    //
    // GET: /Dinners/

    public ActionResult Index() {

        var dinners = dinnerRepository.FindUpcomingDinners().ToList();

        return View("Index", dinners);
    }

    //
    // GET: /Dinners/Details/2

    public ActionResult Details(int id) {

        Dinner dinner = dinnerRepository.GetDinner(id);

        if (dinner == null)
            return View("NotFound");
        else
            return View("Details", dinner);
    }
}

La signature de la méthode d’assistance View() que nous utilisons ci-dessus se présente comme suit :

Capture d’écran de la méthode d’assistance View avec le texte Affichage des résultats (nom de la vue chaîne, modèle objet).

Le premier paramètre de la méthode d’assistance View() est le nom du fichier de modèle d’affichage que nous voulons utiliser pour afficher la réponse HTML. Le deuxième paramètre est un objet de modèle qui contient les données dont le modèle d’affichage a besoin pour afficher la réponse HTML.

Dans notre méthode d’action Index(), nous appelons la méthode d’assistance View() et indiquant que nous voulons afficher une liste HTML des dîners à l’aide d’un modèle d’affichage « Index ». Nous transmettons au modèle d’affichage une séquence d’objets Dinner pour générer la liste à partir de :

//
    // GET: /Dinners/

    public ActionResult Index() {
    
        var dinners = dinnerRepository.FindUpcomingDinners().ToList();
        
        return View("Index", dinners);
    }

Dans notre méthode d’action Details(), nous essayons de récupérer un objet Dinner à l’aide de l’ID fourni dans l’URL. Si un Dîner valide est trouvé, nous appelons la méthode d’assistance View(), indiquant que nous voulons utiliser un modèle d’affichage « Détails » pour restituer l’objet Dinner récupéré. Si un dîner non valide est demandé, nous affichons un message d’erreur utile qui indique que le dîner n’existe pas à l’aide d’un modèle d’affichage « NotFound » (et d’une version surchargée de la méthode d’assistance View() qui prend simplement le nom du modèle) :

//
    // GET: /Dinners/Details/2

    public ActionResult Details(int id) {

        Dinner dinner = dinnerRepository.FindDinner(id);

        if (dinner == null)
            return View("NotFound");
        else
            return View("Details", dinner);
    }

Implémentons maintenant les modèles de vue « NotFound », « Détails » et « Index ».

Implémentation du modèle d’affichage « NotFound »

Nous allons commencer par implémenter le modèle d’affichage « NotFound » qui affiche un message d’erreur convivial indiquant que le dîner demandé est introuvable.

Nous allons créer un modèle d’affichage en positionnant notre curseur de texte dans une méthode d’action du contrôleur, puis cliquer avec le bouton droit et choisir la commande de menu « Ajouter un affichage » (nous pouvons également exécuter cette commande en tapant Ctrl-M, Ctrl-V) :

Capture d’écran du projet avec l’élément de menu Ajouter une vue avec le bouton droit mis en évidence en bleu et cerclé en rouge.

Une boîte de dialogue « Ajouter une vue » s’affiche comme ci-dessous. Par défaut, la boîte de dialogue préremplit le nom de la vue à créer pour qu’il corresponde au nom de la méthode d’action dans laquelle se trouvait le curseur lors du lancement de la boîte de dialogue (dans ce cas, « Détails »). Étant donné que nous voulons d’abord implémenter le modèle « NotFound », nous allons remplacer ce nom d’affichage et le définir sur « NotFound » :

Capture d’écran de la fenêtre Ajouter une vue avec le champ Nom de l’affichage défini sur Introuvable, la case Sélectionner master page cochée et l’id du titulaire du contenu défini sur Contenu principal.

Lorsque nous cliquons sur le bouton « Ajouter », Visual Studio crée un modèle d’affichage « NotFound.aspx » pour nous dans le répertoire « \Views\Dinners » (qu’il créera également si le répertoire n’existe pas déjà) :

Capture d’écran de la hiérarchie de dossiers de fenêtre Explorateur de solutions avec le fichier Point introuvable a s p x mis en évidence en bleu.

Il ouvre également notre nouveau modèle d’affichage « NotFound.aspx » dans l’éditeur de code :

Capture d’écran de la fenêtre de l’éditeur de code avec le point introuvable un fichier s p x ouvert dans l’éditeur de code.

Les modèles d’affichage ont par défaut deux « régions de contenu » où nous pouvons ajouter du contenu et du code. La première nous permet de personnaliser le « titre » de la page HTML renvoyée. La deuxième nous permet de personnaliser le « contenu main » de la page HTML renvoyée.

Pour implémenter notre modèle de vue « NotFound », nous allons ajouter du contenu de base :

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Dinner Not Found
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Dinner Not Found</h2>

    <p>Sorry - but the dinner you requested doesn't exist or was deleted.</p>

</asp:Content>

Nous pouvons ensuite l’essayer dans le navigateur. Pour ce faire, nous allons demander l’URL « /Dinners/Details/9999 ». Cela fait référence à un dîner qui n’existe pas actuellement dans la base de données et entraîne le rendu de notre modèle d’affichage « NotFound » par notre méthode d’action DinnersController.Details() :

Capture d’écran de la fenêtre Mon application MVC avec / Dîners / Détails / 9999 U R L dans la zone d’adresse cerclée en rouge.

Une chose que vous remarquerez dans la capture d’écran ci-dessus est que notre modèle d’affichage de base a hérité d’un ensemble de code HTML qui entoure le contenu main sur l’écran. Cela est dû au fait que notre modèle d’affichage utilise un modèle « master page » qui nous permet d’appliquer une disposition cohérente sur toutes les vues du site. Nous aborderons la façon dont master pages fonctionnent davantage dans une partie ultérieure de ce tutoriel.

Implémentation du modèle d’affichage « Détails »

Implémentons maintenant le modèle d’affichage « Détails » qui générera du code HTML pour un seul modèle Dinner.

Pour ce faire, nous allons positionner notre curseur de texte dans la méthode d’action Détails, puis cliquer avec le bouton droit et choisir la commande de menu « Ajouter une vue » (ou appuyez sur Ctrl-M, Ctrl-V) :

Capture d’écran de la fenêtre de l’éditeur de code montrant l’élément de menu de clic droit Ajouter un point point d’affichage mis en surbrillance en rouge.

La boîte de dialogue « Ajouter une vue » s’affiche. Nous conserverons le nom d’affichage par défaut (« Détails »). Nous allons également cocher la case « Créer une vue fortement typée » dans la boîte de dialogue et sélectionner (à l’aide de la liste déroulante) le nom du type de modèle que nous transmettons du contrôleur à l’affichage. Pour cette vue, nous transmettons un objet Dinner (le nom complet de ce type est : « NerdDinner.Models.Dinner ») :

Capture d’écran de la fenêtre Ajouter une vue avec la liste déroulante Afficher le contenu définie sur Détails et la classe de données View définie sur Nerd Dinner dot Models point Dinner.

Contrairement au modèle précédent, où nous avons choisi de créer un « Affichage vide », cette fois, nous choisirons de « créer automatiquement la structure » de l’affichage à l’aide d’un modèle « Détails ». Nous pouvons l’indiquer en modifiant la liste déroulante « Afficher le contenu » dans la boîte de dialogue ci-dessus.

La « génération de modèles » génère une implémentation initiale de notre modèle d’affichage des détails en fonction de l’objet Dinner que nous lui transmettons. Cela nous permet de démarrer rapidement l’implémentation de notre modèle d’affichage.

Lorsque nous cliquons sur le bouton « Ajouter », Visual Studio crée un nouveau fichier de modèle d’affichage « Details.aspx » pour nous dans notre répertoire « \Views\Dinners » :

Capture d’écran de la fenêtre Explorateur de solutions montrant la hiérarchie des dossiers avec le dossier Dîners mis en évidence en bleu.

Il ouvre également notre nouveau modèle d’affichage « Details.aspx » dans l’éditeur de code. Il contiendra une implémentation initiale de la structure d’une vue de détails basée sur un modèle Dinner. Le moteur de génération de modèles utilise la réflexion .NET pour examiner les propriétés publiques exposées sur la classe qui l’a passé, et ajoutera le contenu approprié en fonction de chaque type qu’il trouve :

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Details
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Details</h2>

    <fieldset>
        <legend>Fields</legend>
        <p>
            DinnerID:
            <%=Html.Encode(Model.DinnerID) %>
        </p>
        <p>
            Title:
            <%=Html.Encode(Model.Title) %>
        </p>
        <p>
            EventDate:
            <%= Html.Encode(String.Format("{0:g}", Model.EventDate)) %>
        </p>
        <p>
            Description:
            <%=Html.Encode(Model.Description) %>
        </p>
        <p>
            HostedBy:
            <%=Html.Encode(Model.HostedBy) %>
        </p>
        <p>
            ContactPhone:
            <%=Html.Encode(Model.ContactPhone) %>
        </p>
        <p>
            Address:
            <%=Html.Encode(Model.Address) %>
        </p>
        <p>
            Country:
            <%=Html.Encode(Model.Country) %>
        </p>
        <p>
            Latitude:
            <%= Html.Encode(String.Format("{0:F}",Model.Latitude)) %>
        </p>
        <p>
            Longitude:
            <%= Html.Encode(String.Format("{0:F}",Model.Longitude)) %>
        </p>
    </fieldset>
    
    <p>
        <%=Html.ActionLink("Edit","Edit", new { id=Model.DinnerID }) %>|
        <%=Html.ActionLink("Back to List", "Index") %>
    </p>
    
</asp:Content>

Nous pouvons demander l’URL « /Dinners/Details/1 » pour voir à quoi ressemble cette implémentation de la structure « détails » dans le navigateur. L’utilisation de cette URL affiche l’un des dîners que nous avons ajoutés manuellement à notre base de données lorsque nous l’avons créée pour la première fois :

Capture d’écran de la fenêtre de réponse de l’application montrant / Dîners / Détails / 1 U R L cerclé en rouge dans la zone d’adresse.

Cela nous permet d’être rapidement opérationnels et de nous fournir une implémentation initiale de notre vue Details.aspx. Nous pouvons ensuite l’ajuster pour personnaliser l’interface utilisateur à notre satisfaction.

Lorsque nous examinons de plus près le modèle Details.aspx, nous constaterons qu’il contient du code HTML statique ainsi que du code de rendu incorporé. <% %> les pépites de code exécutent le code lorsque le modèle d’affichage est rendu, et <%= %> les pépites de code exécutent le code qu’elles contiennent, puis restituent le résultat dans le flux de sortie du modèle.

Nous pouvons écrire du code dans notre vue qui accède à l’objet de modèle « Dinner » transmis à partir de notre contrôleur à l’aide d’une propriété « Model » fortement typée. Visual Studio nous fournit un code intellisense complet lors de l’accès à cette propriété « Model » dans l’éditeur :

Capture d’écran de la fenêtre de l’éditeur de code montrant une liste déroulante avec l’élément Description mise en évidence en bleu.

Nous allons apporter quelques modifications afin que la source de notre dernier modèle de vue Détails ressemble à ce qui suit :

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Dinner: <%=Html.Encode(Model.Title) %>
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2><%=Html.Encode(Model.Title) %></h2>
    <p>
        <strong>When:</strong> 
        <%=Model.EventDate.ToShortDateString() %> 

        <strong>@</strong>
        <%=Model.EventDate.ToShortTimeString() %>
    </p>
    <p>
        <strong>Where:</strong> 
        <%=Html.Encode(Model.Address) %>,
        <%=Html.Encode(Model.Country) %>
    </p>
     <p>
        <strong>Description:</strong> 
        <%=Html.Encode(Model.Description) %>
    </p>       
    <p>
        <strong>Organizer:</strong> 
        <%=Html.Encode(Model.HostedBy) %>
        (<%=Html.Encode(Model.ContactPhone) %>)
    </p>
    
    <%= Html.ActionLink("Edit Dinner", "Edit", new { id=Model.DinnerID })%> |
    <%= Html.ActionLink("Delete Dinner","Delete", new { id=Model.DinnerID})%>   
     
</asp:Content>

Lorsque nous accédons à nouveau à l’URL « /Dinners/Details/1 », elle s’affiche maintenant comme ci-dessous :

Capture d’écran de la fenêtre de réponse de l’application montrant la nouvelle stylisation de la vue dot NET Futures.

Implémentation du modèle d’affichage « Index »

Implémentons maintenant le modèle de vue « Index », qui générera une liste des prochains dîners. Pour ce faire, nous allons positionner notre curseur de texte dans la méthode d’action Index, puis cliquer avec le bouton droit et choisir la commande de menu « Ajouter une vue » (ou appuyer sur Ctrl-M, Ctrl-V).

Dans la boîte de dialogue « Ajouter une vue », nous allons conserver le modèle d’affichage nommé « Index » et cocher la case « Créer une vue fortement typée ». Cette fois, nous allons choisir de générer automatiquement un modèle d’affichage « Liste », puis de sélectionner « NerdDinner.Models.Dinner » comme type de modèle passé à l’affichage (ce qui, comme nous avons indiqué que nous créons une structure « Liste », entraîne le fait que la boîte de dialogue Ajouter une vue suppose que nous passons une séquence d’objets Dinner de notre contrôleur à la vue) :

Capture d’écran de la fenêtre Ajouter une vue avec le nom de l’affichage défini sur Index, la case Créer une vue fortement typée cochée et la case Sélectionner master page cochée.

Lorsque nous cliquez sur le bouton « Ajouter », Visual Studio crée un nouveau fichier de modèle de vue « Index.aspx » pour nous dans notre répertoire « \Views\Dinners ». Il va « créer une structure » une implémentation initiale dans celle-ci qui fournit une liste de table HTML des dîners que nous passons à la vue.

Lorsque nous exécutons l’application et accédons à l’URL « /Dinners/ », elle affiche notre liste de dîners comme suit :

Capture d’écran de la fenêtre de réponse de l’application montrant la liste des dîners dans une disposition de grille après la mise à jour Ajouter une vue.

La solution de table ci-dessus nous donne une disposition de type grille de nos données de dîner , ce qui n’est pas tout à fait ce que nous voulons pour notre liste de dîners destinés aux consommateurs. Nous pouvons mettre à jour le modèle de vue Index.aspx et le modifier pour répertorier moins de colonnes de données, et utiliser un <élément ul> pour les afficher au lieu d’une table à l’aide du code ci-dessous :

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Upcoming Dinners</h2>

    <ul>
        <% foreach (var dinner in Model) { %>
        
            <li>                 
                <%=Html.Encode(dinner.Title) %>            
                on 
                <%=Html.Encode(dinner.EventDate.ToShortDateString())%>
                @
                <%=Html.Encode(dinner.EventDate.ToShortTimeString())%>
            </li>
            
        <% } %>
    </ul>
    
</asp:Content>

Nous utilisons le mot clé « var » dans l’instruction foreach ci-dessus lorsque nous effectuons une boucle sur chaque dîner de notre modèle. Ceux qui ne connaissent pas C# 3.0 peuvent penser que l’utilisation de « var » signifie que l’objet de dîner est lié en retard. Cela signifie plutôt que le compilateur utilise l’inférence de type par rapport à la propriété « Model » fortement typée (qui est de type « IEnumerable<Dinner> ») et compile la variable locale « dinner » en tant que type Dinner, ce qui signifie que nous obtenons une intellisense complète et une vérification au moment de la compilation pour elle dans les blocs de code :

Capture d’écran de la fenêtre de l’éditeur de code montrant un menu déroulant avec l’élément de liste Adresse mis en surbrillance dans une zone en pointillés gris.

Lorsque nous appuyons sur Actualiser sur l’URL /Dinners dans notre navigateur, notre affichage mis à jour ressemble maintenant à ce qui suit :

Capture d’écran de la fenêtre de réponse de l’application montrant la liste des dîners à venir après la commande refresh.

C’est mieux, mais ce n’est pas encore tout à fait là. Notre dernière étape consiste à permettre aux utilisateurs finaux de cliquer sur des dîners individuels dans la liste et d’afficher les détails à leur sujet. Nous allons implémenter cela en rendant les éléments de lien hypertexte HTML liés à la méthode d’action Details sur notre DinnersController.

Nous pouvons générer ces liens hypertexte dans notre vue Index de l’une des deux manières suivantes. La première consiste à créer manuellement un> élément HTML <comme ci-dessous, où nous intégrons <des blocs % %> dans un <> élément HTML :

Capture d’écran de la fenêtre de l’éditeur de code avec le texte de bloc d’une classe et d’un pourcentage mis en surbrillance et cerclé en rouge.

Une autre approche que nous pouvons utiliser consiste à tirer parti de la méthode d’assistance intégrée « Html.ActionLink() » dans ASP.NET MVC qui prend en charge la création par programmation d’un élément HTML <lié à une> autre méthode d’action sur un contrôleur :

<%= Html.ActionLink(dinner.Title, "Details", new { id=dinner.DinnerID }) %>

Le premier paramètre de la méthode d’assistance Html.ActionLink() est le texte de lien à afficher (dans ce cas, le titre du dîner), le deuxième paramètre est le nom de l’action du contrôleur vers lequel nous voulons générer le lien (dans ce cas, la méthode Details), et le troisième paramètre est un ensemble de paramètres à envoyer à l’action (implémenté en tant que type anonyme avec nom/valeurs de propriété). Dans ce cas, nous spécifions le paramètre « id » du dîner auquel nous voulons établir un lien, et parce que la règle de routage d’URL par défaut dans ASP.NET MVC est « {Controller}/{Action}/{id} », la méthode d’assistance Html.ActionLink() génère la sortie suivante :

<a href="/Dinners/Details/1">.NET Futures</a>

Pour notre vue Index.aspx, nous allons utiliser l’approche de méthode d’assistance Html.ActionLink() et avoir chaque dîner dans la liste un lien vers l’URL des détails appropriés :

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Upcoming Dinners
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Upcoming Dinners</h2>

    <ul>
        <% foreach (var dinner in Model) { %>
        
            <li>     
                <%=Html.ActionLink(dinner.Title, "Details", new { id=dinner.DinnerID }) %>
                on 
                <%=Html.Encode(dinner.EventDate.ToShortDateString())%>
                @
                <%=Html.Encode(dinner.EventDate.ToShortTimeString())%>
            </li>
            
        <% } %>
    </ul>
</asp:Content>

Et maintenant, lorsque nous accédons à l’URL /Dinners , notre liste de dîners ressemble à celle ci-dessous :

Capture d’écran de la fenêtre de réponse de l’application qui montre la liste des dîners à venir avec de nouveaux liens correspondant aux éléments de liste.

Lorsque nous cliquez sur l’un des dîners dans la liste, nous allons naviguer pour voir les détails à ce sujet :

Capture d’écran de la fenêtre de réponse de l’application qui montre l’élément de liste sélectionné et les détails qui lui correspondent comme entrés dans la base de données.

Nommage basé sur la convention et structure de répertoires \Views

ASP.NET applications MVC utilisent par défaut une structure de nommage d’annuaires basée sur une convention lors de la résolution des modèles d’affichage. Cela permet aux développeurs d’éviter d’avoir à qualifier entièrement un chemin d’accès d’emplacement lors du référencement de vues à partir d’une classe Controller. Par défaut, ASP.NET MVC recherche le fichier de modèle d’affichage dans le répertoire *\Views[ControllerName]* sous l’application.

Par exemple, nous avons travaillé sur la classe DinnersController, qui référence explicitement trois modèles d’affichage : « Index », « Détails » et « NotFound ». ASP.NET MVC recherche par défaut ces vues dans le répertoire \Views\Dinners sous le répertoire racine de l’application :

Capture d’écran de la fenêtre Explorateur de solutions montrant la hiérarchie des dossiers avec le dossier Dîners mis en évidence dans un rectangle bleu.

Notez ci-dessus comment il existe actuellement trois classes de contrôleur dans le projet (DinnersController, HomeController et AccountController ; les deux dernières ont été ajoutées par défaut lorsque nous avons créé le projet), et qu’il existe trois sous-répertoires (un pour chaque contrôleur) dans le répertoire \Views.

Les vues référencées à partir des contrôleurs Accueil et Comptes résolvent automatiquement leurs modèles d’affichage à partir des répertoires \Views\Home et \Views\Account respectifs. Le sous-répertoire \Views\Shared permet de stocker des modèles d’affichage qui sont réutilisés sur plusieurs contrôleurs au sein de l’application. Lorsque ASP.NET MVC tente de résoudre un modèle d’affichage, il case activée d’abord dans le répertoire spécifique à \Views[Controller], et s’il ne trouve pas le modèle d’affichage, il s’affiche dans le répertoire \Views\Shared.

Lorsqu’il s’agit de nommer des modèles d’affichage individuels, il est recommandé que le modèle d’affichage partage le même nom que la méthode d’action à l’origine de son rendu. Par exemple, au-dessus de notre méthode d’action « Index » utilise la vue « Index » pour afficher le résultat de l’affichage, et la méthode d’action « Détails » utilise la vue « Détails » pour afficher ses résultats. Cela permet de voir rapidement quel modèle est associé à chaque action.

Les développeurs n’ont pas besoin de spécifier explicitement le nom du modèle d’affichage lorsque le modèle d’affichage porte le même nom que la méthode d’action appelée sur le contrôleur. Au lieu de cela, nous pouvons simplement passer l’objet de modèle à la méthode d’assistance « View() » (sans spécifier le nom de la vue), et ASP.NET MVC déduit automatiquement que nous voulons utiliser le modèle de vue \Views[ControllerName][ActionName] sur le disque pour le restituer.

Cela nous permet de propre un peu le code de notre contrôleur et d’éviter de dupliquer deux fois le nom dans notre code :

public class DinnersController : Controller {

    DinnerRepository dinnerRepository = new DinnerRepository();

    //
    // GET: /Dinners/

    public ActionResult Index() {

        var dinners = dinnerRepository.FindUpcomingDinners().ToList();

        return View(dinners);
    }

    //
    // GET: /Dinners/Details/2

    public ActionResult Details(int id) {

        Dinner dinner = dinnerRepository.GetDinner(id);

        if (dinner == null)
            return View("NotFound");
        else
            return View(dinner);
    }
}

Le code ci-dessus est tout ce qui est nécessaire pour implémenter une belle expérience de description/détails du dîner pour le site.

étape suivante

Nous avons maintenant une belle expérience de navigation de dîner construite.

Nous allons maintenant activer la prise en charge de la modification des formulaires de données CRUD (Create, Read, Update, Delete).