• 30 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_certifying

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Mis à jour le 23/11/2017

Mieux organiser son projet avec les Areas

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Plus votre application web va grandir et plus elle va contenir de vues et de contrôleurs. Au bout d’un moment, cela peut vite devenir un gros fouillis jusqu’à ne plus savoir où est quoi.
Pour résoudre ce problème il est possible de découper son application en zones, que l’on appelle en anglais « Areas ». Cela permet notamment de regrouper des éléments par domaine fonctionnel. Reprenons notre exemple d’un site de tutoriels comme le site d'OpenClassrooms. Nous pourrions avoir une zone Tutoriels, une zone Forum, une zone News, une zone pour l’administration, etc.

Voyons comment mettre en place ceci.

Créer une zone

Pour illustrer les zones, je vais créer un petit projet factice qui ne fera pas grand-chose à part vous montrer comment cela fonctionne. Je repars donc d’un projet vierge que j’appelle DemoAreas. J’y ajoute un contrôleur Home  possédant une action Index afin d’avoir une zone principale. Puis j’ajoute une vue toute bête. Bon, tout ça, vous savez faire ;).

Maintenant, ajoutons une zone. Faites un clic droit sur votre projet et choisissez d’ajouter une zone :

Ajout d'une zone
Ajout d'une zone

Et nommez-la par exemple Administration  :

Choix du nom de la zone
Choix du nom de la zone

Visual Studio fait plusieurs choses.
Premièrement, il crée un répertoire Areas contenant un sous-répertoire Administration, contenant des sous répertoires Models, Controllers et Views :

Arborescence après la création d'une zone
Arborescence après la création d'une zone

Bref, quelque chose que l’on connaît bien où nous pourrons mettre des contrôleurs, des vues et un modèle, tout ça dans une zone « Administration  ». Comme un mini-site dans un site.

Deuxièmement, Visual Studio nous a créé un fichier AdministrationAreaRegistration.cs, qui contient le code suivant :

public class AdministrationAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "Administration";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Administration_default",
            "Administration/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );
    }
}

Il s’agit d’une classe qui dérive de la classe de base AreaRegistration . Nous pouvons notamment voir que Visual Studio définit une route spécifique pour notre zone d’administration qu’il préfixe par Administration/.

Maintenant, nous pouvons ajouter des contrôleurs et des vues comme nous savons déjà le faire. Créez par exemple un contrôleur Administration  dans le répertoire /Areas/Administration/Controllers :

public class AdministrationController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

Puis la vue Index.cshtml dans /Areas/Administration/Views/Administration. Bien sûr, si vous utilisez le raccourci pour créer la vue depuis le contrôleur, celle-ci se mettra automatiquement au bon endroit. Elle contient :

@{
ViewBag.Title = "Index d'administration";
}
<h2>Index d'administration</h2>

Recompilez, puis vous pouvez désormais accéder à votre vue d’administration grâce à l’URL suivante /Administration/Administration/Index. Nous retrouvons bien sûr le pattern défini dans la classe que Visual Studio a créé, à savoir "Administration/{controller}/{action}/{id}".

Remarquez que cette nouvelle route est prise en compte par ASP.NET MVC car il existe dans le fichier global.asax.cs une ligne de code qui permet de découvrir et d’enregistrer toutes les zones. Il s’agit de :

AreaRegistration.RegisterAllAreas();

Si vous la commentez, vous verrez que la zone ne fonctionne plus. Mais ne la commentez pas. ;)

Des zones avec des contrôleurs qui portent le même nom

C’est très pratique ces zones, mais nous allons vite rencontrer un problème si vous appelez vos contrôleurs de zones différentes avec le même nom. Dans le chapitre d’avant, pas de problèmes ; nous avions un contrôleur Home , situé dans /Controllers et un contrôleur Administration  situé dans /Areas/Administration/Controllers.

Mais il peut arriver que nous voulions créer un contrôleur Home  dans une zone. Tentez l’expérience et ajoutez un contrôleur Home  dans notre zone Administration.
Puis naviguez sur la racine du site, vous obtenez l’erreur suivante :

Plusieurs types correspondant au contrôleur nommé 'Home' ont été trouvés. Cela peut se produire si la route qui traite cette demande ('{controller}/{action}/{id}') ne spécifie pas d'espaces de noms pour rechercher un contrôleur correspondant à la demande. Si tel est le cas, enregistrez cette route en appelant une surcharge de la méthode 'MapRoute' qui prend un paramètre 'namespaces'.

La demande pour 'Home' a trouvé les contrôleurs correspondants suivants :
DemoAreas.Areas.Administration.Controllers.HomeController
DemoAreas.Controllers.HomeController

L’erreur est plutôt claire, il y a deux fois un HomeController  avec un espace de nom différent. La solution proposée l’est aussi, il vous indique qu’il faut utiliser une surcharge pour passer l’espace de nom lors de la définition de la route.

Regardez l’espace de nom de votre contrôleur principal (chez moi, c’est DemoAreas.Controllers ) et modifiez la route par défaut qui se trouve dans le fichier RouteConfig.cs pour avoir :

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces:new[] { "DemoAreas.Controllers" }
        );
    }
}

Ainsi, en rajoutant la propriété namespaces, j’indique à la route qu’elle doit chercher les contrôleurs dans l’espace de nom DemoAreas.Controllers , comme ça il n’y aura pas de risque de conflit de noms.

Générer une URL vers une action d’un contrôleur d’une zone

Nous avons vu précédemment que le mécanisme de routing était capable de générer une URL à partir d’un nom de contrôleur et d’un nom d’action.
Il sait aussi le faire avec les zones mais nous devons bien sûr utiliser une surcharge différente qui prend en paramètre le nom de la route.

Cela se fait ainsi, par exemple pour créer un lien vers notre contrôleur d’administration :

@Html.ActionLink("Aller à l'écran d'administration", "Index", "Administration", new {area = "Administration"}, null)

On utilise donc le paramètre de route area pour passer le nom de la zone. Et voici le lien qu’il me génère :

<a href="/Administration/Administration">Aller &#224; l&#39;&#233;cran d&#39;administration</a>

Bien sûr, pour une action différente de l’action par défaut (par exemple l’action Voir), nous aurons :

<a href="/Administration/Administration/Voir">Aller à l'écran d'administration</a>

En résumé

  • Les zones (Areas) sont un mécanisme qui permet de mieux organiser son projet quand celui-ci devient grand.

  • Il est possible d’avoir des contrôleurs avec des noms identiques si nous indiquons à la route dans quel espace de nom chercher le contrôleur.

  • Pour générer un lien vers une action d’un contrôleur d’une zone, il faut passer le nom de la zone dans les paramètres de route.

Exemple de certificat de réussite
Exemple de certificat de réussite