C'est mon deuxième article à propos du framework MVC d'ASP.NET 3.5. Vous pouvez lire le premier article qui est une introduction au pattern Model View Controller. Comme nous l'avions vu dans l'introduction, ce pattern propose de décomposer nos projets en trois niveaux : Modèle, Vue et Contrôleur. Lorsque nous créons un projet ASP.NET MVC Application dans Visual Studio 2008 c'est exactement ce que nous retrouvons.
Avant de pouvoir créer un projet vous devez télécharger et installer les extensions ASP.NET 3.5.
Dès que cela est fait, ouvrez Visual Studio et créez un nouveau projet :
- File
- New
- Project
- Une nouvelle fenêtre apparait, sélectionnez "Web -> ASP.NET MVC Web Application".
Visual Studio vous génère alors un template à utiliser pour MVC avec trois dossiers :
Il y a déjà des exemples dedans! Vous pouvez donc lancer le projet pour voir ce que ça donne :
Remarquez bien l'url : http://localhost/Home/About
- "Home" est le nom du contrôleur
- "About" est le nom de l'action que l'ont veut déclencher
Concrètement on a des url du type : http://www.monsite.com/<contrôleur>/<action>/
Ces règles sont configurées dans le global.asax.
[code:c#]
protected void Application_Start(
object sender, EventArgs e)
{
// Note: Change Url= to Url="[controller].mvc/[action]/[id]" to enable
// automatic support on IIS6
RouteTable.Routes.Add(new Route
{
Url = "[controller]/[action]/[id]",
Defaults = new { action = "Index", id = (string)null },
RouteHandler = typeof(MvcRouteHandler)
});
RouteTable.Routes.Add(new Route
{
Url = "Default.aspx",
Defaults = new { controller = "Home", action = "Index", id = (string)null },
RouteHandler = typeof(MvcRouteHandler)
});
}
[/code]
Nous pouvons regarder ce qu'il y a dans les dossiers actuels pour mieux comprendre comment nous pouvons faire évoluer ce projet.
Dans le dossier Model nous n'avons actuellement rien, puisque c'est le dossier qui correspond à tout ce qui est "accès au données". C'est par exemple dans ce dossier que nous viendrons insérer la définition de notre DataContext lorsque nous utiliserons LINQ to SQL.
Dans le dossier View nous avons deux autres dossiers :
Le dossier Home contient toutes les vues (interface) qui sont appelées par le contrôleur "Home". Si nous décidons par la suite d'ajouter un nouveau contrôleur, nous devrons avoir un nouveau dossier avec le nom de ce contrôleur dans notre dossier "view". "Shared" contient notre master page.
Dans le dossier "Controller" nous avons l'ensemble de nos contrôleurs (classe) qui permet de définir les actions en fonction des urls.
Le respect de la hiérarchie des dossiers n'est pas obligatoire mais fortement conseillé!
Nous allons, dans ce projet gérer des albums de musique. Chaque album est répertorié dans une catégorie qui correspond à son genre : pop, rock, classique, rap etc. Nous allons donc créer une base de données pour ce projet :
- Clic droit sur le projet
- Add new item
- Database file (.mdf)
Nous créons les tables pour obtenir le schéma suivant :
A cette base de données nous allons attacher un DataContext qu'on générera à l'aide du designer LINQ to SQL :
- Clic droit sur le dossier "Model".
- Add new item
- LINQ to SQL Classes.
Si vous ne connaissez pas LINQ je vous conseil de regarder les articles que j'ai écris dessus. Pour résumer, c'est un langage de requêtage qui permet d'attaquer de la même façon n'importe quelle source de données. En l'occurence ici, une base de données SQL.
Après avoir ajouter notre datacontext, nous allons l'étendre pour qu'il renvoit des informations utiles au projet :
- Une liste de catégories.
- Une liste d'album d'une catégorie.
- Un album précis.
Pour cela il suffit de recrée une classe partial du même nom que la classe que le designer nous à généré :
[code:c#]
public partial class MusicStoreDataContext
{
public List<Genre> GetCategories()
{
return Genres.ToList();
}
public List<Album> GetAlbumByCategorie(int CatID)
{
return Albums.Where(c => c.Genre.GenreID == CatID).ToList();
}
public Album GetAlbumById(int id)
{
return Albums.Single(a => a.AlbumID == id);
}
}
[/code]
Nous allons maintenant afficher l'ensemble des catégories (correspondant à notre table Genre). Nous allons donc créer un contrôleur "Musiques" :
- Clic droit sur le dossier contrôleur
- Add new item
- MVC Controller class
- Appellez le "MusiquesController".
Vous avez maintenant un nouveau fichier dans le dossier "controller" contenant ceci :
[code:c#]
public class MusiquesController : Controller
{
[ControllerAction]
public void Index()
{
//Add action logic here
}
}
[/code]
Nous aurons donc maintenant des urls de type : http://www.monsite.com/Musiques/...
On voit apparaître un attribut "ControllerAction". Cette méthode est donc une action que l'utilisateur peut effectuer. Ici, par défaut nous avons une action index qui sera lié à une vue. Ici nous n'en avont pas besoin. Nous allons créer plusieurs actions :
- Categories : qui correspondra à l'action pour afficher la liste des catégories. -> /Musiques/Categories
- Liste : qui correspondra à la liste des albums se trouvant dans la catégorie sélectionnée. -> /Musiques/List/<categorie>
- Detail : détail de l'album sélectionné. -> /Musique/Detail/<id_album>
On obtient ceci :
[code:c#]
public class MusiquesController : Controller
{
[ControllerAction]
public void Categories()
{
//Add action logic here
}
[ControllerAction]
public void Liste()
{
//Add action logic here
}
[ControllerAction]
public void Detail()
{
//Add action logic here
}
}
[/code]
Pour le moment nous n'interceptons pas de paramètre. Par exemple pour "Detail" il faudrai récupérer l'id de l'album pour aller chercher ses informations dans la base de données. Pour ça, deux méthodes s'offrent à vous.
Méthode 1 :
[code:c#]
[ControllerAction]
public void Detail(int id)
{
//Add action logic here
}
[/code]
Méthode 2 :
[code:c#]
[ControllerAction]
public void Detail()
{
int id = Convert.ToInt32(Request["id"]);
}
[/code]
Dans les deux cas, nous aurons des urls de ce genre :
- /Musiques/Detail?id=<int id>
- /Musiques/Detail/<int id>
Comment cela se fait il? Souvenez-vous de notre global.asax, il y avait dedans la définition du routage d'url :
[code:c#]
...
Url = "[controller]/[action]/[id]"
...
[/code]
On voit que l'id est défini dans ce fichier global.asax. Concernant les méthodes, c'est naturellement la première que je vous conseil d'utiliser. De la même manière on peut avoir plusieurs paramètres. Par exemple, pour l'action "Liste" on pourrait prévoir une pagination, ce qui entraîne l'utilisation d'un deuxième paramètre optionnel :
[code:c#]
[ControllerAction]
public void Liste(int id, int? page)
{
//Add action logic here
}
[/code]
Ici nous aurons des urls du type : /Musiques/Liste/<id>?page=<numero_page>
Nous allons maintenant remplir nos controller en allant chercher les données nécessaires a nos view :
[code:c#]
using System;
using System.Web;
using System.Web.Mvc;
using MusicStoreMVC.Models;
using System.Collections.Generic;
namespace MusicStoreMVC.Controllers
{
public class MusiquesController : Controller
{
MusicStoreDataContext MusicStore = new MusicStoreDataContext();
[ControllerAction]
public void Categories()
{
List<Genre> Categories = MusicStore.GetCategories();
RenderView("Categories", Categories);
}
[ControllerAction]
public void Liste(int id, int? page)
{
List<Album> Albums = MusicStore.GetAlbumByCategorie(id);
RenderView("Liste", Albums);
}
[ControllerAction]
public void Detail(int id)
{
Album Album = MusicStore.GetAlbumById(id);
RenderView("Detail", Album);
}
}
}
[/code]
On remarque tout d'abord que nous ajoutons bien le namespace "MusicStoreMVC.Models" pour pouvoir utiliser notre datacontext. Ensuite nous fesons juste appel aux méhodes que nous avons écrites plus haut et ensuite nous passons ces données à notre View à l'aide de la méthode RenderView qui prend en paramètre :
- Le nom de la vue a appeler.
- Les données que vous voulez passer à la vue.
Nous allons maintenant (re)définir les vues en commençant par notre MasterPage en y ajoutant un nouveau lien :
[code:xml]
<li><%= Html.ActionLink("Musiques", "Categories", "Musiques")%></li>
[/code]
Ensuite, dans notre dossier view, nous devons ajouter un sous répertoire correspondant au controller. Nous allons donc ajouter un dossier "Categories". C'est dans ce répertoire que nous allons définir les vues correspondants aux actions que nous avons définies dans notre MusiquesController. Nous allons donc y ajouter 3 fichiers aspx :
- Categories.aspx
- Liste.aspx
- Detail.aspx
Choisissez pour chaque page, la bonne MasterPage (située dans View/Shared). Nous devons ensuite aller modifier le code behind. Par défaut une MVC View Content Page dérive de ViewPage pour déjà définir un ensemble d'outils que nous utiliserons plus tard. Lorsque vous passer des datas par la méthode RenderView, alors vous devez typer cet objet pour pouvoir utiliser ensuite les données dont nous avons besoin :
[code:c#]
public partial class Categories : ViewPage< List<Genre> >
{
}
[/code]
Nous devons faire de même pour les deux autres fichiers. Nous devons maintenant afficher les données dans notre page. Pour cela, nous avons plusieurs méthodes. Soit nous programmons un foreach dans la page ASPX, soit nous utilisons un nouveau contrôle ASP.NET 3.5 : ListView. Nous allons voir les deux méthodes même si l'utilisation du ListView est conseillée.
[code:xml]
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Categories.aspx.cs" Inherits="MusicStoreMVC.Views.Musiques.Categories" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContentPlaceHolder" runat="server">
<h2>Liste des catégories</h2>
<% foreach (var categorie in ViewData)
{ %>
* <%= Html.ActionLink(categorie.GenreNom, new { action = "Liste", id = categorie.GenreID })%> <br />
<% } %>
</asp:Content>
[/code]
Pas très propre, mais cela fonctionne :
Lorsque nous cliquons sur une catégorie, nous tombons bien sur une url du genre : /Musiques/Liste/<id>.
Vous remarquez le petit utilitaire pour créer des urls :
[code:c#]
Html.ActionLink(categorie.GenreNom, new { action = "Liste", id = categorie.GenreID })
[/code]
ActionLink prend comme paramètre :
- Le nom du lien
- Un objet anonyme avec une action définie ainsi que les paramètres à envoyer au controller.
Nous pouvons faire exactement la même chose avec le contrôle ListView :
[code:xml]
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="True" CodeBehind="Categories.aspx.cs" Inherits="MusicStoreMVC.Views.Musiques.Categories" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContentPlaceHolder" runat="server">
<h2>Liste des catégories</h2>
<asp:ListView ID="CategorieList" runat="server">
<LayoutTemplate>
<asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<%# Html.ActionLink(Eval("GenreNom").ToString(), new { action = "Liste", id = Eval("GenreID").ToString() }) %> <br />
</ItemTemplate>
<EmptyDataTemplate>
Pas de données.
</EmptyDataTemplate>
</asp:ListView>
[/code]
En ajoutant dans le code behind ceci :
[code:c#]
protected void Page_Load(object sender, EventArgs e)
{
CategorieList.DataSource = ViewData;
CategorieList.DataBind();
}
[/code]
Ce qui donne le même résultat!
/!\ Si vous n'arrivez pas à accéder a vos contrôle dans le code behind, vous devez convertir votre projet en application web :
Voilà notre projet bien avancé et les bases bien posées. Nous continuerons le projet dans des prochains articles en allant plus loin dans les concepts et les fonctionnalités du Framework MVC d'ASP.NET 3.5.
Vos avis / questions en commentaire!
Lire la suite...
Tags:
asp.net,
asp.net 3.5,
mvc
Catégorie :
ASP.NET
Une question sur cet article? n'hésitez pas a me contacter par Live Messegner. Suis-je connecté? 
Actuellement noté 3.0 par 2 personne(s)
- Currently 3/5 Stars.
- 1
- 2
- 3
- 4
- 5
Permalink |
Commentaires (5) |
Post RSS |