• Aucun résultat trouvé

[PDF] Support de cours pratique dot Net et ASP - Cours ASP

N/A
N/A
Protected

Academic year: 2021

Partager "[PDF] Support de cours pratique dot Net et ASP - Cours ASP"

Copied!
77
0
0

Texte intégral

(1)

ASP.NET MVC 5

Document de Rick Anderson

Mise en route

Visual Studio est un environnement de développement intégré ou IDE. Dans Visual Studio, il y a une barre d'outils dans la partie supérieure montrant les différentes options disponibles à vous. Il y a aussi un menu qui fournit un autre moyen d'effectuer des tâches dans l'environnement IDE. (Par exemple, au lieu de sélectionner le Nouveau projet de la page de démarrage, vous pouvez utiliser le menu et sélectionnez Fichier > Nouveau > projet.)

(2)

Créer votre première Application

Cliquez sur Nouveau projet, puis sélectionnez Visual Basic sur la gauche, puis le Web et puis sélectionnez Application Web ASP.NET. Nommez votre projet « MvcMovie » et puis cliquez sur OK.

(3)

Visual Studio utilise un modèle par défaut pour le projet ASP.NET MVC, que vous venez de créer. Vous avez une application qui travaille dès maintenant sans rien faire ! Il s'agit d'un simple projet de « Hello World! ».

Cliquez sur F5 pour démarrer le débogage. F5 oblige Visual Studio à lancer IIS Express et exécutez votre application web Visual Studio puis lance un navigateur et ouvre la page d'accueil de l'application. Remarquez que la barre d'adresse du navigateur affiche localhost:port# . Lorsque Visual Studio exécute un projet web, un port aléatoire est utilisé pour le serveur web. Dans l'image ci-dessous, le numéro de port est 55532. Lorsque vous exécutez l'application, vous verrez un autre numéro de port.

(4)

Dès la sortie de la boite de ce modèle par défaut vous donne des pages Accueil, Contact et environ. L'image ci-dessus n'affiche pas les liens Accueil, propos et Contact. Selon la taille de la fenêtre de votre navigateur, vous devrez peut-être cliquer sur l'icône de navigation pour voir ces liens.

L'application assure également pour vous inscrire et vous connecter. L'étape suivante consiste à modifier le fonctionne de cette application et en savoir un peu plus sur ASP.NET MVC. Fermez l'application ASP.NET MVC et nous allons changer du code.

(5)

Ajout d'un contrôleur

MVC est synonyme de modèle-vue-contrôleur. MVC est un pattern pour développer des applications qui sont bien architecturé, testables et facile à entretenir. Contiennent des applications basées sur le MVC :

Modélisation : Classes qui représentent les données de l'application et qui utilisent une logique de validation pour faire respecter les règles de métier pour que les données.

Views : fichiers de modèle que votre application utilise pour générer dynamiquement les réponses HTML.

Controllers : Classes qui gèrent les demandes entrantes de navigateur, récupérer des données de modèle et ensuite spécifier des modèles de vue qui retournent une réponse au navigateur. Nous couvrant tous ces concepts et vous montrer comment s'en servir pour construire une application. Nous allons commencer par créer une classe de contrôleur.

Dans de L'Explorateur de solutions, faites un clic droit le dossier controllers, puis cliquez sur Ajouter, puis Contrôleur.

(6)

Dans la boite de dialogue Ajouter un modèle automatique, cliquez sur Contrôleur MVC 5 – Vide et puis cliquez sur Ajouter.

Nommez votre nouveau contrôleur « HelloWorldController », puis cliquez sur Ajouter.

Notez que dans L'Explorateur qu'un nouveau fichier a été créé nommé HelloWorldController.vb et un nouveau dossier Views\HelloWorld. Le contrôleur est ouvert dans l'IDE.

(7)

Remplacez le contenu du fichier avec le code suivant. Imports System.Web.Mvc

Public Class HelloWorldController Inherits Controller

' GET: /HelloWorld Function Index() As String

Return "This is my <b>default</b> action..."

End Function

'GET: /HelloWorld/Welcome/ Function Welcome() As String

Return "This is the Welcome action method..."

End Function End Class

Les méthodes du contrôleur retourneront des chaines HTML à titre d'exemple. Le contrôleur est appelé HelloWorldController et la première méthode est nommée Index. Nous allons appeler à partir d'un navigateur. Exécutez l'application (en appuyant sur F5 ou Ctrl + F5). Dans le navigateur, ajoutez « HelloWorld » le chemin d'accès dans la barre d'adresse. (Par exemple, dans l'illustration

(8)

ci-dessous, c'est http://localhost:55532/HelloWorld.) La page dans le navigateur va ressembler à la capture d'écran suivante. Dans la méthode ci-dessus, le code renvoyé une chaine directement.

ASP.NET MVC appelle classes contrôleur différent (et les méthodes d'action différents en leur sein) selon l'URL entrante. La logique de routage d’URL par défaut utilisée par ASP.NET MVC utilise un format comme celui-ci pour déterminer quel code pour appeler :

/[Controller]/[ActionName]/[Parameters]

Vous définissez le format de routage dans le fichier App_Start/RouteConfig.vb. Public Module RouteConfig

Public Sub RegisterRoutes(ByVal routes As RouteCollection) routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

routes.MapRoute( name := "Default",

url := "{controller}/{action}/{id}",

defaults := New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional}

) End Sub End Module

Le slash (/) est un séparateur de segment. Lorsque vous exécutez l'application et ne fournissez pas des segments d'URL, il utilise par défaut le contrôleur « Home » et la méthode d'action « Index » spécifié dans la section valeurs par défaut du code ci-dessus.

La première partie de l'URL détermine la classe du contrôleur à exécuter. Si /HelloWorld est mappé à la classe HelloWorldController. La deuxième partie de l'URL détermine la méthode d'action de la classe à exécuter. Ainsi, /HelloWorld/Index évoquera l’exécution de la méthode Index de la classe HelloWorldController. Notez que /HelloWorld nous renvoie à la même page et le méthode Index a été utilisée par défaut. C'est parce qu'une méthode nommée Index est la méthode par défaut qui sera appelée sur un contrôleur si on n'est pas spécifiée une explicitement. La troisième partie du segment URL (Parameters) est pour acheminer les données.

Accédez à http://localhost:xxxx/HelloWorld/Welcome. Le méthode Welcome s'exécute et retourne la chaine " This is the Welcome action method... ". Le mappage de MVC par défaut est

(9)

/[Controller]/[ActionName]/[Parameters]. Pour cette URL, le contrôleur est HelloWorld et Welcome est la méthode d'action. Vous n'avez pas utilisé la partie [Parameters] de l'URL.

Nous allons modifier l'exemple un peu afin que vous pouvez passer des informations de paramètre de l'URL au contrôleur (par exemple, /HelloWorld/Welcome?name=Scott&numtimes=4). Changer votre méthode Welcome pour inclure deux paramètres comme indiqué ci-dessous. Notez que le code utilise la fonctionnalité de paramètre optionnel vb pour indiquer que le paramètre numTimes a une valeur par défaut égale à 1, si aucune valeur n'est passée pour ce paramètre.

Function Welcome(name As String, Optional numTimes As Integer = 1) As String Return HttpUtility.HtmlEncode("Hello " & name & ", NumTimes is: " & numTimes) End Function

Remarque sur la sécurité : Le code ci-dessus utilise HttpServerUtility.HtmlEncode pour protéger l'application des entrées malveillantes (à savoir le JavaScript).

Lancez votre application et accédez à l'URL de l'exemple (http://localhost:xxxx/HelloWorld/Welcome?name=Scott&numtimes=4). Vous pouvez essayer différentes valeurs pour name et numtimes dans l'URL. Le système de liaison pour le modèle MVC ASP.NET mappe automatiquement les paramètres nommés de la chaine de requête dans la barre d'adresse aux paramètres dans votre méthode.

(10)

Dans l'exemple ci-dessus, le segment d'URL (Parameters) n'est pas utilisé, les paramètres name et numTimes sont transmis sous forme de chaines de requête. Le ? (point d'interrogation) dans l'URL ci-dessus est un séparateur, et suivent les chaines de requête. Le caractère & sépare les chaines de requête.

Remplacez la méthode Welcome avec le code suivant :

Function Welcome(name As String, Optional ID As Integer = 1) As String Return HttpUtility.HtmlEncode("Hello " & name & ", ID: " & ID) End Function

Exécutez l'application et entrez l'URL suivante : http://localhost:xxx/HelloWorld/Welcome/3?name=Rick

Cette fois le troisième segment de l'URL correspondant du paramètre itinéraire ID. La méthode d'action Welcome contient un paramètre (ID) correspondant à la spécification de l'URL dans la méthode RegisterRoutes.

Public Module RouteConfig

Public Sub RegisterRoutes(ByVal routes As RouteCollection) routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

routes.MapRoute( name:="Default",

url:="{controller}/{action}/{id}",

defaults:=New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional}

) End Sub End Module

Dans les applications ASP.NET MVC, il est plus courant pour passer des paramètres en tant que données d'itinéraire (comme nous le faisions avec ID ci-dessus) que les transmettre sous forme de chaines de requête. Vous pourriez également ajouter une route pour passer le name et numtimes dans les paramètres sous forme de données d'itinéraire dans l'URL. Dans le fichier App_Start\RouteConfig.vb, ajoutez la route de "Hello" :

(11)

Exécutez l'application et accédez à /localhost:XXX/HelloWorld/Welcome/Scott/3.

Pour de nombreuses applications MVC, l'itinéraire par défaut fonctionne très bien. Vous apprendrez plus loin dans ce tutoriel comment passer des données à l'aide du modèle, et vous n'aurez pas à modifier l'itinéraire par défaut pour cela.

Dans ces exemples, le contrôleur a fait la partie « VC » de MVC — autrement dit, le travail de vue et le contrôleur. Le contrôleur est de retour HTML directement. Normalement, vous ne souhaitez pas que le contrôleur retour HTML directement, car cela devient très lourd au code. Au lieu de cela, nous utiliserons généralement un fichier de modèle de vue distincte afin de générer la réponse HTML.

Public Module RouteConfig

Public Sub RegisterRoutes(ByVal routes As RouteCollection) routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

routes.MapRoute( name:="Default",

url:="{controller}/{action}/{id}",

defaults:=New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional} ) routes.MapRoute( name:="Hello", url:="{controller}/{action}/{name}/{id}" ) End Sub End Module

(12)

Ajout d'une vue

Dans cette section, vous allez modifier la classe HelloWorldController pour afficher des fichiers de modèle de vue permet d'encapsuler proprement le processus de génération de la réponse HTML à un client.

Vous allez créer un fichier de modèle de vue en utilisant le moteur de vue Razor. Les modèles de vue basée sur le rasoir portent une extension de fichier .vbhtml et fournir un moyen élégant pour créer une sortie HTML à l'aide de vb. Rasoir minimise le nombre de caractères et de keystrokes requis lors de l'écriture d'un modèle de vue et permet un codage rapide et fluide de flux de travail.

Actuellement, la méthode Index retourne une chaine avec un message qui est codé en dur dans la classe de contrôleur. Changer la méthode Index pour renvoyer un objet View, comme illustré dans le code suivant :

Function Index() As ActionResult Return View()

End Function

La méthode Index ci-dessus utilise un modèle de vue générant une réponse HTML dans le navigateur. Les méthodes des contrôleurs (également connues comme des méthodes d'action), telle que la méthode Index ci-dessus, retournent généralement un ActionResult (ou une classe dérivée de ActionResult) et des types non primitifs comme chaine.

Clic droit sur le dossier Views\HelloWorld et cliquez sur Ajouter, puis cliquez sur Page de vue MVC 5 avec disposition (Razor).

Dans la boite de dialogue Spécifier le nom d'élément, entrez Index et puis cliquez sur OK.

(13)

Dans la boite de dialogue Sélectionner une Page de disposition, acceptez la valeur par défaut _Layout.vbhtml, puis cliquez sur OK.

Dans la boite de dialogue ci-dessus, le dossier Views\Shared est sélectionné dans le volet gauche. Si vous aviez un fichier de mise en page personnalisée dans un autre dossier, vous pouvez le sélectionner. Le fichier MvcMovie\Views\HelloWorld\Index.vbhtml est créé.

(14)

Ajoutez la balise suivante de met en évidence. @Code Layout = "~/Views/Shared/_Layout.vbhtml" ViewBag.Title = "Index" End Code <h2>Index</h2>

<p>Hello from our View Template!</p>

Faites un clic droit sur le fichier Index.vbhtml et sélectionnez afficher dans le navigateur.

Vous pouvez également cliquez droit sur le fichier Index.vbhtml et sélectionnez voir en Page inspecteur. Sinon, exécutez l'application et naviguez vers le contrôleur de HelloWorld (http://localhost:xxxx/HelloWorld). La méthode Index dans votre contrôleur n'a pas fait beaucoup de travail ; simplement, il a appelé l'instruction return View(), qui précise que la méthode doit utiliser un fichier de modèle de vue pour restituer une réponse au navigateur. Parce que vous n'a pas spécifier explicitement le nom du fichier du modèle de vue à utiliser, ASP.NET MVC par défaut en utilisant le fichier Index.vbhtml de la vue dans le dossier \Views\HelloWorld. L'image ci-dessous montre la chaîne « Hello from our View Template! » codé en dur dans la vue.

Semble assez bonne. Toutefois, Notez que la barre de titre du navigateur indique « Index – Mon application ASP.NET » et le gros lien en haut de la page dit « Nom de l'Application. ». Selon la

(15)

taille qui fait votre fenêtre de navigateur, vous devrez peut-être cliquez sur les trois barres en haut à droite pour voir les liens Accueil, About, Contact, Inscrivez-vous et Connectez-vous.

Évolution des vues et Pages de disposition

Tout d'abord, vous souhaitez modifier le lien « Nom de l'Application » en haut de la page. Ce texte est commun à toutes les pages. Elle est effectivement appliquée dans un seul endroit dans le projet, même si elle apparait à toutes les pages de l'application. Allez dans le dossier /Views/Shared dans L'Explorateur de solutions et ouvrez le fichier _Layout.vbhtml. Ce fichier s'appelle Layout Page et c'est dans le dossier partagé qui utilisé par toutes les autres pages.

Le modèles de disposition permettent de préciser la disposition de conteneur HTML de votre site en un seul endroit, puis l'appliquer sur plusieurs pages dans votre site. Recherchez la ligne de @RenderBody(). RenderBody est un espace réservé où toutes les pages spécifiques à la vue que vous créez afin d’apparaitre "encapsulés" dans la mise en page. Par exemple, si vous sélectionnez le lien du sA propos de, le point de vue Views\Home\About.vbhtml est restitué à l'intérieur de la méthode RenderBody.

Modifier le contenu de l'élément title. Changer l'ActionLink sur le modèle de mise en page de "Nom de l'Application" à "MVC Movie" et le contrôleur de « Home » à « Movies ». Le fichier complet de mise en page est illustré ci-dessous :

<!DOCTYPE html> <html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - Mon application ASP.NET</title>

@Styles.Render("~/Content/css")

@Scripts.Render("~/bundles/modernizr") </head>

<body>

<div class="navbar navbar-inverse navbar-fixed-top"> <div class="container">

(16)

<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">

<span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button>

@Html.ActionLink("MVC Movie", "Index", "Movies", New With {.area = ""}, New With {.class = "navbar-brand"})

</div>

<div class="navbar-collapse collapse"> <ul class="nav navbar-nav">

<li>@Html.ActionLink("Accueil", "Index", "Home")</li> <li>@Html.ActionLink("À propos de", "About", "Home")</li> <li>@Html.ActionLink("Contact", "Contact", "Home")</li> </ul>

@Html.Partial("_LoginPartial") </div>

</div> </div>

<div class="container body-content"> @RenderBody()

<hr /> <footer>

<p>&copy; @DateTime.Now.Year - My ASP.NET Application</p> </footer>

</div>

@Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required:=False) </body>

</html>

Exécutez l'application et Notez qu'il dit maintenant « MVC Movie ». Cliquez sur le lien A propos de et vous voyez comment cette page affiche aussi "MVC Movie". Nous avons été en mesure d'apporter la modification une fois dans le modèle de disposition et toutes les pages du site ont reflètent le nouveau titre.

(17)

Lorsque nous avons créé tout d'abord le fichier Views\HelloWorld\Index.vbhtml, il contient le code suivant :

@Code

Layout = "~/Views/Shared/_Layout.vbhtml" End Code

Le code de rasoir ci-dessus déclare explicitement la mise en page à utiliser. Examinez le fichier Views\_ViewStart.vbhtml, il contient exactement la balise même de Razor. Le fichier Views\_ViewStart.vbhtml définit la disposition commune utilisée par toutes les vues, donc vous pouvez commenter dehors ou supprimer ce code dans le fichier Views\HelloWorld\Index.vbhtml.

@Code

'Layout = "~/Views/Shared/_Layout.vbhtml" ViewBag.Title = "Index"

End Code <h2>Index</h2>

<p>Hello from our View Template!</p>

Vous pouvez utiliser la propriété de Layout pour définir une vue de la mise en page différente ou la mettre à null si vous voulez qu’aucun fichier de mise en page ne sera utilisé.

Maintenant, nous allons changer le titre de la vue Index. Ouvrez MvcMovie\Views\HelloWorld\Index.vbhtml. Il y a deux endroits pour faire ce changement : tout d'abord, le texte qui apparait dans le titre du navigateur, puis dans l'entête secondaire (l'élément <h2>). Vous leur ferez légèrement différente afin de voir quel morceau de code change quelle partie de l'application.

@Code

Layout = "~/Views/Shared/_Layout.vbhtml" ViewBag.Title = "Movies List"

End Code

<h2>My Movies List</h2>

<p>Hello from our View Template!</p>

Pour indiquer l'élément title de HTML à afficher, le code ci-dessus définit une propriété Title de l'objet ViewBag (qui est dans le modèle d'affichage Index.vbhtml). Notez que le modèle de disposition (Views\Shared\_Layout.vbhtml) utilise cette valeur dans l'élément <title> dans le cadre de la section <head> du code HTML que nous avons modifié précédemment.

<!DOCTYPE html> <html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - Mon application ASP.NET</title>

@Styles.Render("~/Content/css")

@Scripts.Render("~/bundles/modernizr") </head>

(18)

En utilisant l’objet ViewBag, vous pouvez passer facilement d’autres paramètres entre votre modèle d'affichage et votre fichier de mise en page.

Exécutez l'application. Notez que le titre du navigateur, le titre principal et les titres secondaires ont changé. (Si vous ne voyez pas de changements dans le navigateur, il pourrie que vous regardez le contenu mis en cache. Appuyez sur Ctrl + F5 dans votre navigateur pour forcer la réponse du serveur à se charger). Le titre du navigateur est créé avec le ViewBag.Title, nous avons mis dans le modèle de vue Index.vbhtml concaténer à "-Mon application" ajouté dans le fichier de mise en page.

Notez également comment le contenu dans le modèle de vue Index.vbhtml a fusionné avec le modèle d'affichage _Layout.vbhtml et une seule réponse HTML a été envoyée au navigateur. Modèles de disposition rendent vraiment facile de faire les modifications qui s'appliquent dans l'ensemble de toutes les pages dans votre application.

Notre peu de « données » (dans ce cas, le message « Hello from our View Template! ») est codé en dur. Cependant, l'application MVC dispose d'un "V" (vue) et vous avez un "C" (contrôleur), mais pas "M" (modèle) encore.

Passage de données du contrôleur à la vue

Avant que nous allons à intégrer un modèle, parlons de passer des informations du contrôleur à une vue. Les classes contrôleur sont appelés en réponse à une demande d'URL entrante. Une classe de contrôleur est l’endroit où vous écrivez le code qui gère la requête entrante, récupère les données d'une base de données et en fin de compte décide quel type de réponse à envoyer au navigateur. Les modèles de vue sont ensuite utilisables à partir d'un contrôleur pour générer une réponse HTML.

Les contrôleurs sont chargés de fournir toutes les données ou les objets qui sont requis pour un modèle de vue afin de rendre une réponse au navigateur. Exemple : un modèle de vue ne doit jamais exécuter la logique métier ou interagir avec une base de données directement. Au lieu de cela, un modèle de vue devrait fonctionner uniquement avec les données qui sont fournies par le contrôleur. Maintenir cette « séparation des préoccupations » permet de garder votre code propre, testables et plus facile à gérer.

Actuellement, la méthode d'action Welcome dans la classe HelloWorldController prend un name et un paramètre numTimes et ensuite renvoie les valeurs directement dans le navigateur. Plutôt que d'avoir le contrôleur à rendre cette réponse sous forme de chaine, nous allons changer le contrôleur pour utiliser un modèle de vue à la place. Le modèle de vue doit générer une réponse dynamique, ce qui signifie que vous devrez passer des bits de données du contrôleur à la vue afin de générer la réponse. Vous pouvez le faire en passant au niveau du contrôleur les données dynamiques (paramètres) dans un objet ViewBag afin que le modèle de vue puisse accèder.

(19)

Revenez au fichier HelloWorldController.vb et modifiez la méthode Welcome pour ajouter une valeur de Message et NumTimes à l'objet ViewBag. ViewBag est un objet dynamique, ce qui signifie que vous pouvez mettre ce que vous voulez en lui ; l'objet ViewBag n'a aucuns propriétés définis jusqu'à ce que vous mettre quelque chose dedans. Le système de liaison pour le modèle MVC ASP.NET mappe automatiquement les paramètres nommés (name et numTimes) de la chaine de requête dans la barre d'adresse aux paramètres dans votre méthode. Le dossier complet de HelloWorldController.vb ressemble à ceci :

Imports System.Web.Mvc Namespace Controllers

PublicClassHelloWorldController InheritsController

' GET: /HelloWorld

Function Index() AsActionResult Return View()

EndFunction

'GET: /HelloWorld/Welcome/

Function Welcome(name AsString, Optional numTimes AsInteger = 1) AsActionResult ViewBag.Message = "Hello " & name

ViewBag.NumTimes = numTimes Return View()

EndFunction EndClass EndNamespace

L'objet ViewBag contient maintenant des données qui seront transmises automatiquement à l'affichage. Ensuite, vous avez besoin d'un modèle de vue Bienvenue ! Dans le menu générer, sélectionnez Générer la Solution (ou Ctrl + Maj + B) pour s'assurer que le projet est compilé. Clic droit sur le dossier Views\HelloWorld et cliquez sur Ajouter, puis cliquez sur Page de vue MVC 5 avec disposition (Razor).

(20)

Dans la boite de dialogue Spécifier le nom d'élément, entrez Welcome et puis cliquez sur OK. Dans la boite de dialogue Sélectionner une Page de disposition, acceptez la valeur par défaut _Layout.vbhtml, puis cliquez sur OK.

Le fichier MvcMovie\Views\HelloWorld\Welcome.vbhtml est créé.

Remplacez la balise dans le fichier Welcome.vbhtml. Vous allez créer une boucle qui dit « Hello » autant de fois que l'utilisateur dit qu'il se doit. Le dossier complet de Welcome.vbhtml est illustré ci-dessous. @Code ViewBag.Title = "Welcome" End Code <h2>Welcome</h2> <ul> @For i = 1 To ViewBag.NumTimes @<li>@ViewBag.Message</li> Next </ul>

Exécutez l'application, puis accédez à l'URL suivante :

http://localhost:55532/HelloWorld/Welcome?name=Scott&numtimes=4

Maintenant les données sont tirées de l'URL et transmises au contrôleur en utilisant le modèle de binding. Le contrôleur empaquète les données dans un objet ViewBag et passe cet objet à la vue. La vue affiche ensuite les données au format HTML à l'utilisateur.

(21)

Dans l'exemple ci-dessus, nous avons utilisé un objet ViewBag pour transmettre les données du contrôleur à une vue. Plus tard dans ce tutoriel, nous allons utiliser un modèle de vue pour transférer des données d'un contrôleur à une vue. L'approche du modèle de vue pour passer les données est généralement beaucoup plus préférable que l'approche de ViewBag. Eh bien, c'était une sorte de « M » pour le modèle.

(22)

Ajout d'un modèle

Dans cette section, vous ajouterez quelques classes afin de gérer les films dans une base de données. Ces classes seront de la partie « modèle » de l'application ASP.NET MVC.

Vous allez utiliser une technologie d'accès aux données de .NET Framework appelée l'Entity Framework pour définir et travailler avec ces classes du modèle. Entity Framework (souvent dénommé "EF") prend en charge un modèle de développement appelé Code First. Code First vous permet de créer des objets de modèle en utilisant des classes. Vous pourrez ensuite avoir la base de données créée à la volée depuis vos classes, ce qui active à un workflow de développement très propre et rapide.

Ajout de classes de modèle

Dans l'Explorateur de solutions, cliquez droit sur le dossier Models, sélectionnez Ajouter, puis sélectionnez Class.

Entrez le nom de la classe "Movie".

Ajouter les cinq propriétés suivantes à la classe Movie : Namespace Models

Public Class Movie

Public Property ID As Integer Public Property Title As String

Public Property ReleaseDate As DateTime Public Property Genre As String

Public Property Price As Decimal End Class

End Namespace

En plus des propriétés que vous attendez pour modéliser un film, le champ ID est requis par la DB comme la clé primaire.

(23)

Nous allons utiliser la classe Movie pour représenter des films dans une base de données. Chaque instance d'un objet Movie correspondra à une ligne dans une table de base de données, et chaque propriété de la classe Movie sera mappée à une colonne dans la table.

Dans le même fichier, ajoutez la classe Film DBContext suivante : Imports System.Data.Entity

Namespace Models

Public Class Movie

Public Property ID As Integer Public Property Title As String

Public Property ReleaseDate As DateTime

Public Property Genre As String Public Property Price As Decimal End Class

Public Class MovieDbContext Inherits DbContext

Public Property Movies As DbSet(Of Movie) End Class

End Namespace

La classe MovieDBContext représente le Entity Framework contexte de la base de données de film, qui gère l’extraction, le stockage, et la mettre à jour des instances de classe Movie dans une base de données. Le MovieDBContext dérive de la classe de base DbContext fournies par Entity Framework. Afin d'être en mesure de faire référence DbContext et DbSet, vous devez ajouter l'instruction Imports suivante en haut du fichier :

Imports System.Data.Entity

Vous pouvez le faire en tapant manuellement l'instruction Imports, ou vous pouvez cliquer sur la ligne rouge squiggly sous DbContext, appuyez sur Maj + Alt + F10 et choisissez Importer 'System.Data.Entity' dans le menu contextuel.

Création d'une chaine de connexion et de travail avec SQL Server

LocalDB

La classe MovieDBContext que vous avez créé gère la tâche de se connecter à la base de données et le mapping des objets de films à des enregistrements de base de données. Une question que vous pourriez demander, cependant, est de savoir comment spécifier quelle base de données sera utilisée. Vous n'avez pas réellement de spécifier quelle base de données à utiliser, Entity Framework utilise par défaut LocalDB. Dans cette section, nous allons ajouter explicitement une chaine de connexion dans le fichier web.config de l'application.

(24)

SQL Server Express LocalDB

LocalDB est une version allégée du moteur de base de données SQL Server Express qui commence à la demande et fonctionne en mode utilisateur. LocalDB fonctionne dans un mode d'exécution spéciale de SQL Server Express qui vous permet de travailler avec des bases de données enregistrer des fichiers .mdf. En règle générale, les fichiers de base de données LocalDB sont conservés dans le dossier App_Data d'un projet web.

Par défaut, le Entity Framework regarde dans le fichier web.config pour une chaine de connexion portant le même nom que la classe de contexte de l'objet (MovieDBContext pour ce projet). Ouvrez le fichier web.config à la racine de l'application. (Attention il y a un autre fichier web.config dans le dossier Vues.)

Chercher l'élément <connectionStrings>:

Ajouter la chaine de connexion suivante à l'élément <connectionStrings> dans le fichier web.config.

(25)

<add name="MovieDBContext" connectionString="Data

Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Movies.mdf;Initial Catalog=Movies;Integrated Security=True" providerName="System.Data.SqlClient" />

L'exemple suivant montre une partie du fichier web.config avec le nouveau connectionstring ajouté :

<connectionStrings>

<add name="DefaultConnection" connectionString="Data

Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-MvcMovie-20160314123831.mdf;Initial Catalog=aspnet-MvcMovie-20160314123831;Integrated Security=True" providerName="System.Data.SqlClient" />

<add name="MovieDBContext" connectionString="Data

Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Movies.mdf;Initial Catalog=Movies;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>

Les deux chaines de connexion sont très similaires. La première chaine de connexion est nommée DefaultConnection et elle est utilisé pour la base de données des membres pour contrôler qui peut accéder à l'application. La chaine de connexion que vous avez ajoutée spécifie une base de données LocalDB nommée Movie.mdf situé dans le dossier App_Data.

Le nom de la chaine de connexion doit correspondre au nom de la classe DbContext. Public Class MovieDbContext

Inherits DbContext

Public Property Movies As DbSet(Of Movie) End Class

Vous pouvez nommer la base de données avec le nom que vous voulez, tant qu'il a le suffixe .mdf. Par exemple, nous pourrions nommer la base de données MyFilms.mdf.

Vous allez construire une nouvelle classe de contrôleur de film que vous pouvez utiliser pour afficher les données de films et de permettre aux utilisateurs de créer de nouvelles listes de films.

Avant de faire ceci il faut régénère le projet : Build > Générez MVCMovie (Sinon vous obtiendrez une erreur dans les sections suivantes). Nous avons finalement ajouté un modèle à votre application MVC.

Scaffolding un contrôleur

(26)

Dans la boite de dialogue Ajouter un modèle automatique, appuyez sur Contrôleur MVC 5 avec vues, en utilisant Entity Framework > Ajouter.

Remplissez la boite de dialogue Ajouter un contrôleur :

Classe de modèle : Movie (MvcMovie.Models)

Classe de contexte de données : MovieDbContext (MvcMovie.Models)

 Vues : Gardez les valeurs par défaut de chaque option cochée

 Nom du contrôleur : Gardez la valeur par défaut « MoviesController »

Cliquer sur Ajouter

Le moteur de visuel studio de scaffolding crée les éléments suivants :

(27)

Un répertoire Views\Movies

 Les fichiers de vue Razor : Create, Delete, Details, Edit et Index

Visual Studio crée automatiquement le CRUD (créer, lire, mettre à jour et supprimer) les méthodes d'action et des vues pour vous (la création automatique de CRUD méthodes d'action et des vues est connu sous le nom Scaffolding). Vous aurez bientôt une application web entièrement fonctionnel qui vous permet de créer, liste, modifier et supprimer des entités de Movies.

Exécutez l'application et parcourir au contrôleur de Movies en ajoutant /Movies à l'URL dans la barre d'adresse de votre navigateur. Parce que l'application repose sur le routage par défaut (défini dans le fichier App_Start\RouteConfig.vb), la demande navigateur http://localhost:55532/Movies est acheminé par défaut à la méthode d'action Index du contrôleur Movies. En d'autres termes, la requête http://localhost:55532/Movies est effectivement la même requête http://localhost:55532/Movies/Index. Le résultat est une liste vide de films, parce que vous ne l'avez pas encore ajouté.

Création d'un film

Sélectionnez le lien Create New. Entrez quelques détails sur un film et puis cliquez sur le bouton Create.

(28)

Remarque : En fonction de vos paramètres régionaux, vous ne pouvez pas être en mesure d'entrer des points ou des virgules décimales dans le champ Price. Pour soutenir la validation jQuery pour les paramètres régionaux non anglais qui utilisent une virgule (",") pour un point décimal, et les formats de date non US-anglais, vous devez inclure globalize.js et vos spécifiques au fichier cultures/globalize.cultures.js (à partir https://github.com/jquery/globalize) et JavaScript pour utiliser Globalize.parseFloat. L’utilisation de ceci sera comment faire plus tard. Pour l'instant, il suffit d'entrer des nombres entiers comme 10.

Le clique sur le bouton Create New provoque l’affichage du formulaire sur le serveur, où l'information de film est enregistrée dans la base de données. Vous êtes alors redirigé vers le URL /Movies, où vous pouvez voir le film nouvellement créé dans la liste.

(29)

Créer plus d'entrées. Essayez les liens de Edit, Details et Delete, qui sont tous fonctionnels.

Examiner le code généré

Ouvrez le fichier Controllers\MoviesController.vb et examiner la méthode Index générée. Une partie du contrôleur de Movies avec la méthode index est présentée ci-dessous.

Namespace Controllers

Public Class MoviesController

Inherits System.Web.Mvc.Controller Private db As New MovieDbContext ' GET: Movies

Function Index() As ActionResult Return View(db.Movies.ToList()) End Function

Une demande au contrôleur Movies renvoie toutes les entrées de la table des Movies, puis transmet les résultats à la vue de l'index. La ligne suivante de la classe MoviesController instancie un contexte de base de données de Movie, comme décrit précédemment. Vous pouvez utiliser le contexte de base de données Movie pour interroger, modifier et supprimer des films.

Private db As New MovieDbContext

Modèles fortement typées et le mots-clé @ModelType

Plus tôt dans ce tutoriel, vous avez vu comment un contrôleur peut transmettre des données ou des objets à un modèle de vue en utilisant l'objet ViewBag. Le ViewBag est un objet dynamique qui fournit un moyen à liaison tardive pratique pour transmettre des informations à une vue.

(30)

MVC offre également la possibilité de passer des objets fortement typés à une vue. Cette approche fortement typée permet de mieux vérifier votre code et d’utiliser IntelliSense dans l'éditeur Visual Studio lors de la compilation. Le mécanisme de Scaffolding dans Visual Studio utilisé cette approche (qui est, le passage d'un modèle fortement typé) avec la classe MoviesController et les Templates de vues quand il a créé les méthodes et les vues.

Dans le fichier Controllers\MoviesController.vb, examine la méthode générée Details. La méthode Details est illustré ci-dessous.

' GET: Movies/Details/5

Function Details(ByVal id As Integer?) As ActionResult If IsNothing(id) Then

Return New HttpStatusCodeResult(HttpStatusCode.BadRequest) End If

Dim movie As Movie = db.Movies.Find(id) If IsNothing(movie) Then

Return HttpNotFound() End If

Return View(movie) End Function

Le paramètre id est généralement passé en tant que données de routage, par exemple http://localhost:55532/Movies/Details/1 définiront le contrôleur au contrôleur de Movies, l'action à Details et l'identifiant à 1. Vous pouvez également passer dans le id avec la chaine de requête comme suit :

http://localhost:55532/movies/details?id=1

Si un film est trouvé, une instance du modèle de Movie est passé à la vue Details: Return View(movie)

Examinez le contenu du fichier Views\Movies\Details.vbhtml : @ModelType MvcMovie.Models.Movie

@Code

ViewData("Title") = "Details" End Code <h2>Details</h2> <div> <h4>Movie</h4> <hr /> <dl class="dl-horizontal"> <dt> @Html.DisplayNameFor(Function(model) model.Title) </dt> <dd> @Html.DisplayFor(Function(model) model.Title) </dd> <dt> @Html.DisplayNameFor(Function(model) model.ReleaseDate) </dt> <dd> @Html.DisplayFor(Function(model) model.ReleaseDate) </dd>

(31)

<dt> @Html.DisplayNameFor(Function(model) model.Genre) </dt> <dd> @Html.DisplayFor(Function(model) model.Genre) </dd> <dt> @Html.DisplayNameFor(Function(model) model.Price) </dt> <dd> @Html.DisplayFor(Function(model) model.Price) </dd> </dl> </div> <p>

@Html.ActionLink("Edit", "Edit", New With { .id = Model.ID }) | @Html.ActionLink("Back to List", "Index")

</p>

En incluant une déclaration de type @ModelType au début du fichier Template vue, vous pouvez spécifier le type d'objet que la vue attend. Lorsque vous avez créé le contrôleur de Movies, Visual Studio automatiquement inclus la déclaration suivante de @ModelType en haut du fichier Details.vbhtml en se basant sur le modèle de la classe que vous avez sélectionné lors de l'ajout du contrôleur :

@ModelType MvcMovie.Models.Movie

Cette directive @ModelType vous permet d'accéder au film que le contrôleur passé à la vue à l'aide d'un objet de modèle qui est fortement typée. Par exemple, dans la vue Details.vbhtml, le code passe chaque champ de film pour les Helpers HTML DisplayNameFor et DisplayFor avec l'objet du modèle fortement typé. Les méthodes Create et Edit et les vues templates passent également un objet de modèle de film.

Examinez la vue Index.vbhtml et la méthode Index dans le contrôleur MoviesController.vb. Remarquez comment le code crée un objet de la liste quand il appelle la méthode View dans la méthode d'action Index. Ainsi, Le code passe cette liste de films à partir de la méthode d'action Index à la vue.

Function Index() As ActionResult

Return View(db.Movies.ToList()) End Function

Lorsque vous avez créé le contrôleur de Movie, Visual Studio inclus automatiquement la déclaration @ModelType à la partie supérieure du fichier Index.vbhtml :

@ModelType IEnumerable(Of MvcMovie.Models.Movie)

Cette directive @ModelType, vous permet d'accéder à la liste des films que le contrôleur transmis à la vue à l'aide d'un objet modèle qui est fortement typée. Par exemple, dans la vue Index.vbhtml, le code itère sur les films en faisant une instruction For Each sur l’objet fortement typé du Modèle :

@For Each item In Model @<tr>

(32)

@Html.DisplayFor(Function(modelItem) item.Title) </td> <td> @Html.DisplayFor(Function(modelItem) item.ReleaseDate) </td> <td> @Html.DisplayFor(Function(modelItem) item.Genre) </td> <td> @Html.DisplayFor(Function(modelItem) item.Price) </td> <td>

@Html.ActionLink("Edit", "Edit", New With {.id = item.ID }) |

@Html.ActionLink("Details", "Details", New With {.id = item.ID }) |

@Html.ActionLink("Delete", "Delete", New With {.id = item.ID })

</td> </tr> Next

Parce que l’objet modèle est fortement typé (comme étant l’objet IEnumerable<Movie>), chaque objet item dans la boucle est typé comme étant Movie. Ceci vous accorde plusieurs avantages tels que : l’obtention des vérifications lors de la compilation du code et le support complet de l’IntelliSense dans l'éditeur de code :

Travailler avec SQL Server LocalDB

Entity Framework Code First a détecté que la chaine de connexion de base de données qui a été fourni pointe vers une base de données nommé Movies et qui n'existait pas encore. Ainsi l’approche code First créé la base de données automatiquement. Vous pouvez vérifier qu'il a été créé en regardant dans le dossier App_Data. Si vous ne voyez pas le fichier Movies.mdf, cliquez sur le bouton Afficher tous les fichiers dans la barre d'outils de l’Explorateur de solutions, cliquez sur le bouton Refresh, puis développez le dossier App_Data.

(33)

Double-cliquez sur Movies.mdf pour ouvrir SERVER EXPLORER, puis développez le dossier tables pour voir la table Movies. Notez l'icône de clé à côté de ID. Par défaut, EF fera de la propriété ID une clé primaire.

(34)

Cliquez droit sur la table Movies et sélectionnez Show Table Data pour voir les données que vous avez créé.

Cliquez droit sur la table Movies et sélectionnez Open Table definition afin de voir la structure de table que l’Entity Framework Code First a créé pour vous.

(35)

Remarquez comment le schéma de la Table Movies se liée à la classe Movie que vous avez créé précédemment. L’Entity Framework Code First créé automatiquement ce schéma pour vous en fonction de votre classe Movie.

(36)

Lorsque vous aurez terminé, fermer la connexion en cliquant à droite de MovieDBContext et en sélectionnant Fermer la connexion. (Si vous ne fermez pas la connexion, vous pourriez obtenir une erreur la prochaine fois que vous exécutez le projet).

Vous avez maintenant une base de données et les pages pour afficher, modifier, mettre à jour et supprimer des données.

(37)

Examinant les méthodes Edit et la vue Edit

Vous allez examiner la méthode d'action généré Edit et sa vue associée pour le contrôleur Movie. Mais tout d'abord nous allons modifier le modèle afin de mieux afficher la date de sortie. Ouvrez le fichier Models\Movie.vb et ajoutez les lignes surbrillance ci-dessous :

Imports System.ComponentModel.DataAnnotations Imports System.Data.Entity

Namespace Models Public Class Movie

Public Property ID As Integer Public Property Title As String <Display(Name:="Release Date")> <DataType(DataType.Date)>

<DisplayFormat(DataFormatString:="{0:yyyy-MM-dd}", ApplyFormatInEditMode:=True)>

Public Property ReleaseDate As DateTime Public Property Genre As String

Public Property Price As Decimal End Class

Public Class MovieDbContext Inherits DbContext

Public Property Movies As DbSet(Of Movie) End Class

End Namespace

Vous pouvez également faire la culture de date spécifique comme ceci :

<DisplayFormat(DataFormatString:="{0:d}", ApplyFormatInEditMode:=True)> Nous couvrirons DataAnnotations plus-tard. L'attribut Display spécifie ce qu'il faut afficher pour le nom d'un champ (en l'occurrence "Release Date" au lieu de « ReleaseDate»). L'attribut DataType spécifie le type des données, dans ce cas c'est une date, pour les moment les informations stockées dans le champ n'est pas affiché. L'attribut DisplayFormat est nécessaire pour un bug dans le navigateur de Chrome qui restitue les formats de date incorrecte.

Exécutez l'application et naviguez vers le contrôleur Movies. Maintenez le pointeur de la souris sur un lien Edit pour voir l'URL à lequel il fait référence.

(38)

Le lien Edit a été généré par la méthode Html.ActionLink de le vue Views\Movies\Index.vbhtml :

@Html.ActionLink("Edit", "Edit", New With {.id = item.ID }) |

L'objet Html est une aide (Helper) qui exposé en utilisant une propriété de la classe de base System.Web.Mvc.WebViewPage. La méthode ActionLink du Helper facilite la génération dynamiquement des liens hypertexte HTML qui pointent vers des méthodes d'action des contrôleurs. Le premier argument à la méthode ActionLink est le texte rendu en lien hypertexte (par exemple, <a>Edit Me</a>). Le second argument est le nom de la méthode d'action à appeler (dans ce cas, l'action Edit). Le dernier argument est un objet anonyme qui génère les données de parcours (dans ce cas, l'ID de 4).

Le lien généré montré dans l'image précédente est http://localhost:55532/films/Edit/3. L'itinéraire par défaut (créé en App_Start\RouteConfig.vb) prend le modèle d'URL {controller}/{action}/{id}. Par conséquent, ASP.NET traduit l’URL http://localhost: 55532/films/Edit/3 par une requête à la méthode d'action Edit du contrôleur Movies avec le paramètre ID qui est vaut 3. Examinez le code suivant dans le fichier App_Start\RouteConfig.vb. La méthode MapRoute est utilisé pour router les requêtes HTTP vers le bon contrôleur, en choisissant la méthode d'action et en fournissant le paramètre d'ID qui est facultatif. La méthode MapRoute est également utilisée par les HtmlHelpers comme ActionLink pour générer des URL en fournissant le contrôleur, la méthode d'action et des données de parcours.

Public Module RouteConfig

Public Sub RegisterRoutes(ByVal routes As RouteCollection) routes.IgnoreRoute("{resource}.axd/{*pathInfo}") routes.MapRoute(

name:="Default",

url:="{controller}/{action}/{id}",

defaults:=New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional} ) routes.MapRoute( name:="Hello", url:="{controller}/{action}/{name}/{id}" ) End Sub End Module

Vous pouvez également passer des paramètres de méthode d'action à l'aide d'une chaine de requête. Par exemple, l'URL http://localhost:55532/Movies/Edit?ID=3 passe également le paramètre ID de 3 pour la méthode d'action Edit du contrôleur Movies.

(39)

Ouvrir le contrôleur Movies. Les deux méthodes d'action Edit figurent ci-dessous. ' GET: Movies/Edit/5

Function Edit(ByVal id As Integer?) As ActionResult If IsNothing(id) Then

Return New HttpStatusCodeResult(HttpStatusCode.BadRequest) End If

Dim movie As Movie = db.Movies.Find(id) If IsNothing(movie) Then

Return HttpNotFound() End If

Return View(movie) End Function

(40)

' POST: Movies/Edit/5

'Afin de déjouer les attaques par sur-validation, activez les propriétés spécifiques que vous voulez lier. Pour

'plus de détails, voir http://go.microsoft.com/fwlink/?LinkId=317598. <HttpPost()>

<ValidateAntiForgeryToken()>

Function Edit(<Bind(Include:="ID,Title,ReleaseDate,Genre,Price")> ByVal movie As Movie) As ActionResult

If ModelState.IsValid Then

db.Entry(movie).State = EntityState.Modified db.SaveChanges()

Return RedirectToAction("Index") End If

Return View(movie) End Function

Noter que la deuxième méthode d'action Edit est précédée de l'attribut HttpPost. Cet attribut spécifie que cette surcharge de la méthode Edit est appelée uniquement pour les requêtes POST. Vous pouvez appliquer l'attribut HttpGet à la première méthode Edit, mais ce n'est pas nécessaire, parce que c'est la valeur par défaut. L'attribut Bind est un autre mécanisme de sécurité important qui empêche les pirates de trop poster des données à votre modèle. Vous ne devez inclure que les propriétés que vous souhaitez modifier dans l'attribut Bind. Dans ce modèle simple utilisé dans ce tutoriel, nous engagerons toutes les données du modèle. L'attribut ValidateAntiForgeryToken est utilisé pour prévenir la falsification d'une demande et est jumelé avec @Html.AntiForgeryToken() dans le fichier de vue Edit (Views\Movies\Edit.vbhtml), une partie est illustrée ci-dessous :

@ModelType MvcMovie.Models.Movie @Code

ViewData("Title") = "Edit" End Code <h2>Edit</h2> @Using (Html.BeginForm()) @Html.AntiForgeryToken() @<div class="form-horizontal"> <h4>Movie</h4> <hr />

@Html.ValidationSummary(True, "", New With { .class = "text-danger" }) @Html.HiddenFor(Function(model) model.ID)

<div class="form-group">

@Html.LabelFor(Function(model) model.Title, htmlAttributes:= New With { .class = "control-label col-md-2" })

<div class="col-md-10">

@Html.EditorFor(Function(model) model.Title, New With { .htmlAttributes = New With { .class = "form-control" } })

@Html.ValidationMessageFor(Function(model) model.Title, "", New With { .class = "text-danger" })

</div> </div>

@Html.AntiForgeryToken() génère un jeton masqué d'anti-contrefaçon dans le formulaire qui doit correspondre dans la méthode Edit du contrôleur Movies. Ceci afin de se prévenir contre des attaque de type Cross-site request forgery (XSRF ou CSRF).

(41)

La méthode Edit de HttpGet prend le paramètre ID de film, cherche un film à l'aide de la méthode Find de l’Entity Framework et retourne le film sélectionné à la vue Edit. Si un film est introuvable, HttpNotFound est retourné. Lorsque le système de scaffolding créé la vue Edit, il examine la classe Movie et il crée le code pour restituer des éléments <label> et <input> pour chaque propriété de la classe. L'exemple suivant montre l'affichage de Edit qui a été généré par le système de scaffolding de visual studio :

@ModelType MvcMovie.Models.Movie @Code

ViewData("Title") = "Edit" End Code <h2>Edit</h2> @Using (Html.BeginForm()) @Html.AntiForgeryToken() @<div class="form-horizontal"> <h4>Movie</h4> <hr />

@Html.ValidationSummary(True, "", New With { .class = "text-danger" }) @Html.HiddenFor(Function(model) model.ID)

<div class="form-group">

@Html.LabelFor(Function(model) model.Title, htmlAttributes:= New With { .class = "control-label col-md-2" })

<div class="col-md-10">

@Html.EditorFor(Function(model) model.Title, New With { .htmlAttributes = New With { .class = "form-control" } })

@Html.ValidationMessageFor(Function(model) model.Title, "", New With { .class = "text-danger" })

</div> </div>

<div class="form-group">

@Html.LabelFor(Function(model) model.ReleaseDate, htmlAttributes:= New

With { .class = "control-label col-md-2" })

<div class="col-md-10">

@Html.EditorFor(Function(model) model.ReleaseDate, New With { .htmlAttributes = New With { .class = "form-control" } })

@Html.ValidationMessageFor(Function(model) model.ReleaseDate, "", New With { .class = "text-danger" })

</div> </div>

<div class="form-group">

@Html.LabelFor(Function(model) model.Genre, htmlAttributes:= New With { .class = "control-label col-md-2" })

<div class="col-md-10">

@Html.EditorFor(Function(model) model.Genre, New With { .htmlAttributes = New With { .class = "form-control" } })

@Html.ValidationMessageFor(Function(model) model.Genre, "", New With { .class = "text-danger" })

</div> </div>

<div class="form-group">

@Html.LabelFor(Function(model) model.Price, htmlAttributes:= New With { .class = "control-label col-md-2" })

(42)

@Html.EditorFor(Function(model) model.Price, New With { .htmlAttributes = New With { .class = "form-control" } })

@Html.ValidationMessageFor(Function(model) model.Price, "", New With { .class = "text-danger" })

</div> </div>

<div class="form-group">

<div class="col-md-offset-2 col-md-10">

<input type="submit" value="Save" class="btn btn-default" /> </div>

</div> </div> End Using <div>

@Html.ActionLink("Back to List", "Index") </div>

@Section Scripts

@Scripts.Render("~/bundles/jqueryval") End Section

Remarquez comment le modèle d'affichage a une déclaration de @model MvcMovie.Models.Movie en haut du fichier, cette option indique que la vue attend le modèle pour le modèle d'affichage de type Movie.

Le code structure utilise plusieurs méthodes d'assistance pour rationaliser le balisage HTML. Le helper Html.LabelFor affiche le nom du champ ("Title", "Date de sortie", "Genre" ou "Prix"). Le helper Html.EditorFor restitue un élément <input> de HTML. Le helper Html.ValidationMessageFor affiche des messages de validation associés à cette propriété.

Exécutez l'application et accédez à l'URL /Movies. Cliquez sur un lien Edit. Dans le navigateur, affichez le code source de la page. Ci-dessous le code HTML du formulaire.

<form action="/Movies/Edit?ID=3" method="post">

<input name="__RequestVerificationToken" type="hidden"

value="hcnE5fWGPpFxQBshcjpw6uirYXpxjMLaKwpxZndVKTj4p-o9ByjdZXRrPV-LTp5aip_FjCEah3HK2RJre5VGoYL-SvPKrnNciJ6vhQxRXls1" /> <div

class="form-horizontal">

<h4>Movie</h4> <hr />

<input data-val="true" data-val-number="The field ID must be a number." data-val-required="Le champ ID est requis." id="ID" name="ID" type="hidden" value="3" />

<div class="form-group">

<label class="control-label col-md-2" for="Title">Title</label> <div class="col-md-10">

<input class="form-control text-box single-line" id="Title" name="Title" type="text" value="Example 2" />

<span class="field-validation-valid text-danger" data-valmsg-for="Title" data-valmsg-replace="true"></span>

</div> </div>

<div class="form-group">

<label class="control-label col-md-2" for="ReleaseDate">Release Date</label>

(43)

<input class="form-control text-box single-line" data-val="true" data-val-date="The field Release Date must be a date." data-val-required="Le champ Release Date est requis." id="ReleaseDate" name="ReleaseDate" type="date"

value="2014-02-28" />

<span class="field-validation-valid text-danger" data-valmsg-for="ReleaseDate" data-valmsg-replace="true"></span>

</div> </div>

<div class="form-group">

<label class="control-label col-md-2" for="Genre">Genre</label> <div class="col-md-10">

<input class="form-control text-box single-line" id="Genre" name="Genre" type="text" value="Action" />

<span class="field-validation-valid text-danger" data-valmsg-for="Genre" data-valmsg-replace="true"></span>

</div> </div>

<div class="form-group">

<label class="control-label col-md-2" for="Price">Price</label> <div class="col-md-10">

<input class="form-control text-box single-line" data-val="true" data-val-number="The field Price must be a number." data-val-required="Le champ Price est requis." id="Price" name="Price" type="text" value="22,00" />

<span class="field-validation-valid text-danger" data-valmsg-for="Price" data-valmsg-replace="true"></span>

</div> </div>

<div class="form-group">

<div class="col-md-offset-2 col-md-10">

<input type="submit" value="Save" class="btn btn-default" /> </div>

</div> </div> </form>

Les éléments <input> sont dans un élément <form> de HTML dont l'attribut action a la valeur post à l'URL /Movies/Edit. Les données de formulaire seront affichées sur le serveur lorsqu'un clic est effectué sur le bouton Save. La seconde ligne montre le jeton caché XSRF généré par l'appel de @Html.AntiForgeryToken().

Traitement de la demande POST

Le Code suivant affiche la version HttpPost de la méthode d'action Edit. <HttpPost()>

<ValidateAntiForgeryToken()>

Function Edit(<Bind(Include:="ID,Title,ReleaseDate,Genre,Price")> ByVal movie As Movie) As ActionResult

If ModelState.IsValid Then

db.Entry(movie).State = EntityState.Modified db.SaveChanges()

Return RedirectToAction("Index") End If

Return View(movie) End Function

L'attribut ValidateAntiForgeryToken valide le jeton XSRF généré par l'appel de @Html.AntiForgeryToken() dans la vue.

(44)

Le modèle Binder de ASP.NET MVC prend les valeurs du formulaire affiché et crée un objet de Movie qui est passé comme paramètre nommée movie. La méthode ModelState.IsValid vérifie que les données fournies dans le formulaire peuvent servir afin de modifier (éditer ou mise à jour) un objet Movie. Si les données sont valides, les données du film sont enregistrées dans la collection Movies de l’objet db (instance de MovieDBContext). Les nouvelles données sont enregistrées dans la base de données en appelant la méthode SaveChanges de MovieDBContext. Après avoir sauvegardé les données, le code redirige l'utilisateur vers la méthode d'action Index de la classe MoviesController, qui affiche la liste des films, y compris les changements que vient d’être appliqués.

Dès la validation côté client, l’application détermine les valeurs d'un champ qui ne sont pas valides et affiche un message d'erreur. Si vous désactivez JavaScript, vous n'aurez pas la validation côté client, mais le serveur détecte que les valeurs envoyées ne sont pas valides, et les valeurs de la forme vont être réaffichées avec des messages d'erreur. Plus tard dans le tutoriel, nous examinons validation plus en détail.

Les helpers Html.ValidationMessageFor dans le modèle d'affichage Edit.vbhtml prendre soin d'afficher les messages d'erreur appropriées.

(45)

Toutes les méthodes HttpGet suivent un modèle similaire. Ils identifient un objet film (ou une liste d'objets, dans le cas Index) et passent le modèle à la vue. La méthode Create passe un objet film vide à la vue de la création. Toutes les méthodes qui créer, modifier, supprimer ou modifient des données dans le cas contraire va le faire dans la surcharge HttpPost de la méthode. La modification des données dans une méthode HTTP GET engendre un risque pour la sécurité. La modification de données dans une méthode GET viole également les meilleures pratiques HTTP et le modèle architectural de reste, qui stipule que les requêtes GET ne devraient pas changer l'état de votre application. En d'autres termes, une opération GET doit être une opération sécuritaire qui n'a aucuns effets secondaires et ne modifie pas vos données persistantes.

Noter que : afin de supporter la validation de jQuery pour les paramètres régionaux non anglais qui utilisent une virgule («, ») pour un point décimal et les formats de date non US-anglais, vous devez inclure le fichier globalize.js et votre fichier spécifique cultures/globalize.cultures.js (depuis

(46)

https://github.com/jquery/globalize) et l’utilisation de JavaScript pour utiliser Globalize.parseFloat. Vous pouvez obtenir la validation de non-anglais jQuery de NuGet.

1. Dans le menu Outils, cliquez sur Gestionnaire de Package NuGet et puis cliquez sur Gérer les Packages NuGet de Solution.

2. Dans le volet gauche, sélectionnez Online ou Parcourir. (Voir l'image ci-dessous). 3. Dans la zone de saisie de recherche, entrez Globalize.

Cliquez sur installer puis Ok. Le fichier Scripts\globalize.js sera ajouté à votre projet. Le dossier Scripts\globalize\ contient de nombreux fichiers JavaScript de culture.

Le code suivant montre les modifications dans le fichier Views\Movies\Edit.vbhtml : @Section Scripts

@Scripts.Render("~/bundles/jqueryval")

<script src="~/Scripts/globalize/globalize.js"></script> <script

src="~/Scripts/globalize/cultures/globalize.culture.@(System.Threading.Thread.Curren tThread.CurrentCulture.Name).js"></script>

<script>

$.validator.methods.number = function (value, element) { return this.optional(element) ||

(47)

}

$(document).ready(function () {

Globalize.culture('@(System.Threading.Thread.CurrentThread.CurrentCulture.Name)'); });

</script> <script>

jQuery.extend(jQuery.validator.methods, { range: function (value, element, param) {

//Use the Globalization plugin to parse the value var val = Globalize.parseFloat(value);

return this.optional(element) || ( val >= param[0] && val <= param[1]); }

});

$.validator.methods.date = function (value, element) { return this.optional(element) || Globalize.parseDate(value) || Globalize.parseDate(value, "yyyy-MM-dd"); } </script> } End Section

Pour éviter de répéter ce code dans chaque vue d'édition, vous pouvez la déplacer vers le fichier de mise en page.

Comme une solution temporaire, si vous ne pouvez pas obtenir validation travaillant dans vos paramètres régionaux, vous pouvez forcer votre ordinateur à utiliser en anglais américain ou vous pouvez désactiver le JavaScript dans votre navigateur. Pour forcer votre ordinateur à utiliser en anglais américain, vous pouvez ajouter l'élément globalization dans le fichier web.config de projets racine. Le code suivant montre l'élément globalization avec la culture mises à l'anglais des États-Unis.

<system.web>

<globalization culture ="en-US" /> <!--elements removed for clarity--> </system.web>

(48)

Ajout d'une méthode de recherche et sa vue

Dans cette section, vous allez ajouter des capacités de recherche de la méthode d'action Index qui vous permet de rechercher des films par genre, ou nom.

Mise à jour de la forme Index

Commencez par mettre à jour la méthode d'action Index à la classe existante MoviesController. Voici le code :

' GET: Movies

Function Index(ByVal searchString As String) As ActionResult

Dim movies = From m In db.Movies Select m If Not String.IsNullOrEmpty(searchString) Then

movies = movies.Where(Function(movie) movie.Title.Contains(searchString)) End If

Return View(movies) End Function

La première ligne de la méthode Index crée la requête LINQ suivante pour sélectionner les films :

Dim movies = From m In db.Movies Select m

La requête est définie à ce stade, mais n'a pas encore été exécutée sur la base de données. Si le paramètre searchString contient une chaine, la requête est modifiée pour filtrer sur la valeur de la chaine de recherche, en utilisant le code suivant :

If Not String.IsNullOrEmpty(searchString) Then

movies = movies.Where(Function(movie) movie.Title.Contains(searchString)) End If

Le code Function(movie) ci-dessus est une Expression Lambda. Lambdas sont utilisés dans les méthode fondée sur les requêtes LINQ en tant qu'arguments aux méthodes d'opérateur de requête standard telles que la méthode Where utilisé dans le code ci-dessus. Les requêtes LINQ ne sont pas exécutées lorsqu'elles sont définies ou lorsqu'elles sont modifiées en appelant une méthode telle que Where ou OrderBy. Au lieu de cela, l’exécution de la requête est différée, ce qui signifie que l'évaluation d'une expression est retardée jusqu'à ce que sa valeur réalisée soit effectivement parcourue ou la méthode ToList est appelée. Dans une recherche simple, la requête est exécutée dans la vue Index.vbhtml. Note : la méthode Contains est exécutée sur la base de données quand vous LINQ aux entites, et n’ont pas dans le code vb précédent. Dans la base de données, Contains mappe vers l’opérateur LIKE de SQL, qui est insensible à la casse.

Maintenant vous pouvez mettre à jour la vue Index qui affiche le formulaire à l'utilisateur. Exécutez l'application et naviguez jusqu'à /Movies/Index. Ajoutez à l'URL une chaine de requête comme ?searchString=xe. Les films filtrés sont affichés.

Références

Documents relatifs

Une distinction importante s’effectue ainsi : la reconstitution architecturale, à laquelle est associée une signification scientifique précise, n’a pas la même

La variation régionale des souches (diversité et fréquence) révélée dans cette étude peut être un indicateur de la variation régionale de la pathogénicité et de

Les préparations furent exposées dans le nouveau cabinet de Roy du Château d’Alfort et Fragonard acquit une certaine notoriété.. Il fut sollicité par l’aristocratie et reçu

Aussi, une étude en IRM morphométrique a corrélé une hypertrophie du bulbe olfactif chez des AP avec cette sensibilité olfactive augmentée (Rombaux et al., 2010) alors

Les féministes intervenant dans les maisons d’hébergement tentent d’offrir des solutions concrètes aux femmes, leur permettant d’éviter les situations dangereuses pour

Dans leur célèbre ouvrage L’acteur et le système 6 , les sociologues Michel Crozier et Erhard Friedberg posent pourtant une question cruciale pour l’étude des politiques publiques

ainsi, pour ce dernier aspect, qu'une étude mettant en évidence le décalage entre l'offre de zones aménagées pour les activités économiques et le flux

Os consumidores estão mais conscientes sobre os benefícios de alimentos mais naturais em relação aos processados e ultraprocessados.. Pesquisa recente da Sociedade Brasileira de