Partager via


Application à une seule page : modèle KnockoutJS

Le modèle Knockout MVC fait partie de ASP.NET et Web Tools 2012.2

Télécharger ASP.NET et Web Tools 2012.2

La mise à jour ASP.NET et Web Tools 2012.2 inclut un modèle d’application Single-Page (SPA) pour ASP.NET MVC 4. Ce modèle est conçu pour vous aider à créer rapidement des applications web interactives côté client.

« Application monopage » (SPA) est le terme général d’une application web qui charge une seule page HTML, puis met à jour la page dynamiquement, au lieu de charger de nouvelles pages. Après le chargement initial de la page, le spa communique avec le serveur via des requêtes AJAX.

Diagramme montrant deux zones intitulées Client et Serveur. Une flèche intitulée AJAX passe du client au serveur. Une flèche intitulée H T L et une flèche nommée J SON vont du serveur au client.

AJAX n’est rien de nouveau, mais il existe aujourd’hui des frameworks JavaScript qui facilitent la création et la maintenance d’une grande application SPA sophistiquée. En outre, HTML 5 et CSS3 facilitent la création d’interfaces utilisateur enrichies.

Pour commencer, le modèle SPA crée un exemple d’application de liste de tâches. Dans ce tutoriel, nous allons suivre une visite guidée du modèle. Nous allons tout d’abord examiner l’application de liste de tâches elle-même, puis examiner les éléments technologiques qui la font fonctionner.

Créer un projet de modèle SPA

Conditions requises :

  • Visual Studio 2012 ou Visual Studio Express 2012 pour le web
  • ASP.NET mise à jour de Web Tools 2012.2. Vous pouvez installer la mise à jour ici.

Démarrez Visual Studio et sélectionnez Nouveau projet dans la page Démarrer. Ou, dans le menu Fichier , sélectionnez Nouveau , puis Projet.

Dans le volet Modèles , sélectionnez Modèles installés et développez le nœud Visual C# . Sous Visual C#, sélectionnez Web. Dans la liste des modèles de projet, sélectionnez ASP.NET application web MVC 4. Nommez le projet, puis cliquez sur OK.

Capture d’écran montrant la boîte de dialogue Nouveau projet. Une application web SP dot NET M V C 4 est sélectionnée dans la liste des modèles web.

Dans l’Assistant Nouveau projet , sélectionnez Application monopage.

Capture d’écran montrant la boîte de dialogue Nouveau projet A P.P. dot NET M V C 4. Le modèle Application monopage est sélectionné.

Appuyez sur F5 pour générer et exécuter l’application. Lorsque l’application s’exécute pour la première fois, elle affiche un écran de connexion.

Capture d’écran montrant l’écran de connexion My To do List.

Cliquez sur le lien « S’inscrire » et créez un utilisateur.

Capture d’écran montrant l’écran d’inscription.

Une fois connecté, l’application crée une liste todo par défaut avec deux éléments. Vous pouvez cliquer sur « Ajouter une liste de tâches » pour ajouter une nouvelle liste.

Capture d’écran montrant deux listes à faire et un bouton Ajouter à la liste de tâches en haut.

Renommez la liste, ajoutez des éléments à la liste et case activée-les. Vous pouvez également supprimer des éléments ou supprimer une liste entière. Les modifications sont automatiquement conservées dans une base de données sur le serveur (en fait LocalDB à ce stade, car vous exécutez l’application localement).

Capture d’écran montrant une liste avec trois éléments. Le dernier élément est vérifié et est barré.

Architecture du modèle SPA

Ce diagramme montre les main blocs de construction de l’application.

Diagramme montrant les blocs de construction distincts du client et du serveur. Knockout dot j s, H T M L et J SON sont sous Client. Un point S P.NET M V C, un point S.P.P. web A P.P., Entity Framework et une base de données se trouvent sous Serveur.

Côté serveur, ASP.NET MVC sert le code HTML et gère également l’authentification basée sur les formulaires.

API Web ASP.NET gère toutes les demandes liées aux ToDoLists et ToDoItems, y compris l’obtention, la création, la mise à jour et la suppression. Le client échange des données avec l’API web au format JSON.

Entity Framework (EF) est la couche O/RM. Il intermédiat entre le monde orienté objet de ASP.NET et la base de données sous-jacente. La base de données utilise LocalDB, mais vous pouvez le modifier dans le fichier Web.config. En règle générale, vous utilisez LocalDB pour le développement local, puis vous déployez sur une base de données SQL sur le serveur, à l’aide de la migration ef code-first.

Côté client, la bibliothèque Knockout.js gère les mises à jour des pages à partir des requêtes AJAX. Knockout utilise la liaison de données pour synchroniser la page avec les données les plus récentes. De cette façon, vous n’avez pas besoin d’écrire le code qui parcoure les données JSON et met à jour le DOM. Au lieu de cela, vous placez des attributs déclaratifs dans le code HTML qui indiquent à Knockout comment présenter les données.

Un grand avantage de cette architecture est qu’elle sépare la couche de présentation de la logique d’application. Vous pouvez créer la partie API web sans savoir à quoi ressemblera votre page web. Côté client, vous créez un « modèle d’affichage » pour représenter ces données, et le modèle de vue utilise Knockout pour la liaison au code HTML. Cela vous permet de modifier facilement le code HTML sans modifier le modèle d’affichage. (Nous allons voir Knockout un peu plus tard.)

Modèles

Dans le projet Visual Studio, le dossier Models contient les modèles utilisés côté serveur. (Il existe également des modèles côté client; nous allons y accéder.)

Capture d’écran montrant le dossier Models ouvert.

TodoItem, TodoList

Il s’agit des modèles de base de données pour Entity Framework Code First. Notez que ces modèles ont des propriétés qui pointent les uns vers les autres. ToDoList contient une collection de ToDoItems, et chacun ToDoItem a une référence à son toDoList parent. Ces propriétés sont appelées propriétés de navigation, et elles représentent la relation un-à-plusieurs une liste de tâches et ses éléments de tâches.

La ToDoItem classe utilise également l’attribut [ForeignKey] pour spécifier que ToDoListId est une clé étrangère dans la ToDoList table. Cela indique à EF d’ajouter une contrainte de clé étrangère à la base de données.

[ForeignKey("TodoList")]
public int TodoListId { get; set; }
public virtual TodoList TodoList { get; set; }

TodoItemDto, TodoListDto

Ces classes définissent les données qui seront envoyées au client. « DTO » signifie « objet de transfert de données ». Le DTO définit la façon dont les entités seront sérialisées au format JSON. En général, il existe plusieurs raisons d’utiliser des DTO :

  • Pour contrôler les propriétés sérialisées. Le DTO peut contenir un sous-ensemble des propriétés du modèle de domaine. Vous pouvez le faire pour des raisons de sécurité (pour masquer des données sensibles) ou simplement pour réduire la quantité de données que vous envoyez.
  • Pour modifier la forme des données, par exemple pour aplatir une structure de données plus complexe.
  • Pour empêcher toute logique métier d’être en dehors du DTO (séparation des préoccupations).
  • Si vos modèles de domaine ne peuvent pas être sérialisés pour une raison quelconque. Par exemple, les références circulaires peuvent entraîner des problèmes lorsque vous sérialisez un objet Il existe des moyens de gérer ce problème dans l’API web (voir Gestion des références d’objets circulaires) ; mais l’utilisation d’un DTO évite tout simplement le problème.

Dans le modèle SPA, les DTO contiennent les mêmes données que les modèles de domaine. Toutefois, elles restent utiles, car elles évitent les références circulaires à partir des propriétés de navigation et illustrent le modèle DTO général.

AccountModels.cs

Ce fichier contient des modèles pour l’appartenance au site. La UserProfile classe définit le schéma des profils utilisateur dans la base de données d’appartenance. (Dans ce cas, les seules informations sont l’ID utilisateur et le nom d’utilisateur.) Les autres classes de modèle de ce fichier sont utilisées pour créer les formulaires d’inscription et de connexion de l’utilisateur.

Entity Framework

Le modèle SPA utilise EF Code First. Dans le développement Code First, vous définissez d’abord les modèles dans le code, puis EF utilise le modèle pour créer la base de données. Vous pouvez également utiliser EF avec une base de données existante (Base de données d’abord).

La TodoItemContext classe dans le dossier Models dérive de DbContext. Cette classe fournit la « colle » entre les modèles et EF. contient TodoItemContext une ToDoItem collection et une TodoList collection. Pour interroger la base de données, il vous suffit d’écrire une requête LINQ sur ces collections. Par exemple, voici comment sélectionner toutes les listes de tâches pour l’utilisateur « Alice » :

TodoItemContext db = new TodoItemContext();
IEnumerable<TodoList> lists = 
    from td in db.TodoLists where td.UserId == "Alice" select td;

Vous pouvez également ajouter de nouveaux éléments à la collection, mettre à jour des éléments ou supprimer des éléments de la collection, et conserver les modifications apportées à la base de données.

contrôleurs API Web ASP.NET

Dans API Web ASP.NET, les contrôleurs sont des objets qui gèrent les requêtes HTTP. Comme mentionné précédemment, le modèle SPA utilise l’API web pour activer les opérations CRUD sur ToDoList les instances et ToDoItem . Les contrôleurs se trouvent dans le dossier Contrôleurs de la solution.

Capture d’écran montrant le dossier Contrôleurs ouvert. Pour faire Le point c s du contrôleur et le point c de la liste à faire, les deux sont cerclées en rouge.

  • TodoController: gère les requêtes HTTP pour les éléments à faire
  • TodoListController: gère les requêtes HTTP pour les listes de tâches.

Ces noms sont significatifs, car l’API web correspond au chemin d’ACCÈS URI au nom du contrôleur. (Pour savoir comment l’API web achemine les requêtes HTTP vers les contrôleurs, consultez Routage dans API Web ASP.NET.)

Examinons la ToDoListController classe. Il contient un seul membre de données :

private TodoItemContext db = new TodoItemContext();

TodoItemContext est utilisé pour communiquer avec EF, comme décrit précédemment. Les méthodes du contrôleur implémentent les opérations CRUD. L’API web mappe les requêtes HTTP du client aux méthodes de contrôleur, comme suit :

Demande HTTP Controller, méthode Description
GET /api/todo GetTodoLists Obtient une collection de listes de tâches.
GET /api/todo/id GetTodoList Obtient une liste de tâches par ID
PUT /api/todo/id PutTodoList Mises à jour une liste de tâches.
POST /api/todo PostTodoList Crée une liste de tâches.
DELETE /api/todo/id DeleteTodoList Supprime une liste TODO.

Notez que les URI de certaines opérations contiennent des espaces réservés pour la valeur d’ID. Par exemple, pour supprimer une liste de to avec l’ID 42, l’URI est /api/todo/42.

Pour en savoir plus sur l’utilisation de l’API web pour les opérations CRUD, consultez Création d’une API web qui prend en charge les opérations CRUD. Le code de ce contrôleur est assez simple. Voici quelques points intéressants :

  • La GetTodoLists méthode utilise une requête LINQ pour filtrer les résultats en fonction de l’ID de l’utilisateur connecté. De cette façon, un utilisateur ne voit que les données qui lui appartiennent. Notez également qu’une instruction Select est utilisée pour convertir les ToDoList instances en TodoListDto instances.
  • Les méthodes PUT et POST case activée l’état du modèle avant de modifier la base de données. Si ModelState.IsValid a la valeur false, ces méthodes retournent HTTP 400, Requête incorrecte. Pour en savoir plus sur la validation des modèles dans API web, consultez Validation du modèle.
  • La classe de contrôleur est également décorée avec l’attribut [Authorize]. Cet attribut vérifie si la requête HTTP est authentifiée. Si la demande n’est pas authentifiée, le client reçoit HTTP 401, Non autorisé. Pour en savoir plus sur l’authentification, consultez Authentification et autorisation dans API Web ASP.NET.

La TodoController classe est très similaire à TodoListController. La plus grande différence est qu’il ne définit aucune méthode GET, car le client obtient les éléments à faire avec chaque liste de tâches.

Vues et contrôleurs MVC

Les contrôleurs MVC se trouvent également dans le dossier Contrôleurs de la solution. HomeControlleraffiche le code HTML main de l’application. La vue du contrôleur de base est définie dans Views/Home/Index.cshtml. La vue Accueil affiche un contenu différent selon que l’utilisateur est connecté ou non :

@if (@User.Identity.IsAuthenticated)
{
    // ....
}

Lorsque les utilisateurs sont connectés, ils voient l’interface utilisateur main. Sinon, ils voient le panneau de connexion. Notez que ce rendu conditionnel se produit côté serveur. N’essayez jamais de masquer du contenu sensible côté client: tout ce que vous envoyez dans une réponse HTTP est visible par quelqu’un qui regarde les messages HTTP bruts.

Client-Side JavaScript et Knockout.js

Nous allons maintenant passer du côté serveur de l’application au client. Le modèle SPA utilise une combinaison de jQuery et de Knockout.js pour créer une interface utilisateur fluide et interactive. Knockout.js est une bibliothèque JavaScript qui facilite la liaison du code HTML à des données. Knockout.js utilise un modèle appelé « Model-ViewModel ».

  • Le modèle est les données de domaine (listes ToDo et éléments ToDo).
  • La vue est le document HTML.
  • Le modèle de vue est un objet JavaScript qui contient les données du modèle. Le modèle d’affichage est une abstraction de code de l’interface utilisateur. Il n’a aucune connaissance de la représentation HTML. Au lieu de cela, il représente des fonctionnalités abstraites de la vue, telles que « une liste d’éléments ToDo ».

La vue est liée aux données du modèle d’affichage. Mises à jour au modèle d’affichage sont automatiquement répercutés dans la vue. Les liaisons fonctionnent également dans l’autre sens. Les événements du DOM (tels que les clics) sont liés aux données aux fonctions du modèle d’affichage, qui déclenchent des appels AJAX.

Le modèle SPA organise le Code JavaScript côté client en trois couches :

  • todo.datacontext.js : envoie les requêtes AJAX.
  • todo.model.js : définit les modèles.
  • todo.viewmodel.js : définit le modèle d’affichage.

Diagramme montrant une flèche allant de Knockout point j s à Afficher le modèle vers Les modèles vers le contexte de données. La flèche entre Knockout point j s et View Model est étiquetée Liaison de données et pointe vers les deux éléments.

Ces fichiers de script se trouvent dans le dossier Scripts/application de la solution.

Capture d’écran montrant le sous-dossier étiqueté application ouvert.

todo.datacontext gère tous les appels AJAX aux contrôleurs d’API web. (Les appels AJAX pour la connexion sont définis ailleurs, dans ajaxlogin.js.)

todo.model.js définit les modèles côté client (navigateur) pour les listes de tâches. Il existe deux classes de modèle : todoItem et todoList.

La plupart des propriétés des classes de modèle sont de type « ko.observable ». Les observables sont la façon dont Knockout fait sa magie. Dans la documentation Knockout : Une observable est un « objet JavaScript qui peut informer les abonnés des modifications ». Lorsque la valeur d’une observable change, Knockout met à jour tous les éléments HTML liés à ces observables. Par exemple, todoItem a des observables pour les propriétés title et isDone :

self.title = ko.observable(data.title);
self.isDone = ko.observable(data.isDone);

Vous pouvez également vous abonner à un observable dans le code. Par exemple, la classe todoItem s’abonne aux modifications apportées aux propriétés « isDone » et « title » :

saveChanges = function () {
    return datacontext.saveChangedTodoItem(self);
};

// Auto-save when these properties change
self.isDone.subscribe(saveChanges);
self.title.subscribe(saveChanges);

Afficher le modèle

Le modèle d’affichage est défini dans todo.viewmodel.js. Le modèle d’affichage est le point central où l’application lie les éléments de page HTML aux données de domaine. Dans le modèle SPA, le modèle d’affichage contient un tableau observable de todoLists. Le code suivant dans le modèle d’affichage indique à Knockout d’appliquer les liaisons :

ko.applyBindings(window.todoApp.todoListViewModel);

HTML et liaison de données

Le code HTML main de la page est défini dans Views/Home/Index.cshtml. Étant donné que nous utilisons la liaison de données, le code HTML n’est qu’un modèle pour ce qui est réellement rendu. Knockout utilise des liaisons déclaratives . Vous liez des éléments de page à des données en ajoutant un attribut « data-bind » à l’élément. Voici un exemple très simple, tiré de la documentation de Knockout :

<p>There are <span data-bind="text: myItems().count"></span> items<p>

Dans cet exemple, Knockout met à jour le contenu de l’élément <span> avec la valeur .myItems.count() Chaque fois que cette valeur change, Knockout met à jour le document.

Knockout fournit un certain nombre de types de liaison différents. Voici quelques-unes des liaisons utilisées dans le modèle SPA :

  • foreach : vous permet d’itérer à travers une boucle et d’appliquer le même balisage à chaque élément de la liste. Il est utilisé pour afficher les listes de tâches et les éléments à faire. Dans le foreach, les liaisons sont appliquées aux éléments de la liste.
  • visible : permet de désactiver la visibilité. Masquer le balisage lorsqu’une collection est vide ou rendre le message d’erreur visible.
  • value : utilisé pour remplir des valeurs de formulaire.
  • click : lie un événement click à une fonction sur le modèle d’affichage.

Anti-CSRF Protection

La falsification de requête intersite (CSRF) est une attaque par laquelle un site malveillant envoie une requête à un site vulnérable où l’utilisateur est actuellement connecté. Pour empêcher les attaques CSRF, ASP.NET MVC utilise des jetons anti-falsification, également appelés jetons de vérification des demandes. L’idée est que le serveur place un jeton généré de manière aléatoire dans une page web. Lorsque le client envoie des données au serveur, il doit inclure cette valeur dans le message de demande.

Les jetons anti-falsification fonctionnent parce que la page malveillante ne peut pas lire les jetons de l’utilisateur, en raison de stratégies de même origine. (Les stratégies de même origine empêchent les documents hébergés sur deux sites différents d’accéder au contenu de l’autre.)

ASP.NET MVC fournit une prise en charge intégrée des jetons anti-falsification, via la classe AntiForgery et l’attribut [ValidateAntiForgeryToken]. Actuellement, cette fonctionnalité n’est pas intégrée à l’API web. Toutefois, le modèle SPA inclut une implémentation personnalisée pour l’API web. Ce code est défini dans la ValidateHttpAntiForgeryTokenAttribute classe, qui se trouve dans le dossier Filtres de la solution. Pour en savoir plus sur l’anti-CSRF dans l’API web, consultez Prévention des attaques par falsification de requête intersite (CSRF).

Conclusion

Le modèle SPA est conçu pour vous aider à commencer rapidement à écrire des applications web modernes et interactives. Il utilise la bibliothèque Knockout.js pour séparer la présentation (balisage HTML) de la logique des données et de l’application. Mais Knockout n’est pas la seule bibliothèque JavaScript que vous pouvez utiliser pour créer un SPA. Si vous souhaitez explorer d’autres options, consultez les modèles SPA créés par la communauté.