MVC 3 – Routing – Partie 7

Pour repartir d’un bon pied voici le code-behind du fichier global.asax.cs que nous allons utiliser :

public static void RegisterRoutes(RouteCollection routes)
{
  routes.MapRoute("Route 2", "{controller}/{action}/{pseudonyme}/{*poubelle}",
                   new { controller = "Home", action = "Index", pseudonyme = UrlParameter.Optional });
}

Si on résume nos URL’s peuvent être composées de 0,1,2…n parties :

  • Partie 1 : Le nom du controller, par défaut Home si elle n’est pas fournie
  • Partie 2 : L’action du controller, par défaut Index si elle n’est pas fournie.
  • Partie 3 : Le pseudonyme de la personne, ce paramètre est optionnel.
  • Partie 4…n : Si l’utilisateur met d’autres parties à son URL’s alors ces parties seront stockées dans notre variable nommée poubelle.

1) La gestion des doublons de namespace

 

Même si ce n’est pas le cas le plus courant penchons-nous sur le problème suivant :

On va créer un nouveau répertoire dans notre projet TestMVCRouting, personnellement je vais l’appeler OtherControllers. Maintenant je vais créer une classe nommée HomeController qui hérite de Controller. Très bien et maintenant lancement de l’application qui va planter et dont voici un aperçu :

Erreur si plusieurs namespace définissent une classe au nom équivalent.

Que nous dit cette erreur, tout simplement que deux classes sont nommées HomeController et qu’il ne sait bien entendu pas laquelle prendre. Heureusement le moteur de routing MVC 3 a pensé à ce cas là et voici en une ligne de code comment lui préciser que nous souhaitons juste utiliser les classes présentes dans le namespace TestMVCRouting.Controllers (pour plus de clarté je suis passé à la ligne entre chaque paramètres de la méthode MapRoute).

 public static void RegisterRoutes(RouteCollection routes)
 {
   routes.MapRoute("Route 2",
          "{controller}/{action}/{pseudonyme}/{*poubelle}",
          new { controller = "Home", action = "Index", pseudonyme = UrlParameter.Optional },
          new[] { "TestMVCRouting.Controllers" });
 }

On peut ajouter bien entendu plusieurs autres namespaces vu que l’on traite un tableau de string. Attention si nous avions mis les deux namespaces contenant nos classes HomeController nous aurions obtenu une erreur car le framework va aller chercher dans tous les namespaces référencés, quelque soit leurs ordre de déclaration.

La ligne que nous avons ajouté ne fait que prioriser le namespace. C’est à dire, lors de la décomposition de l’URL, le framework MVC 3 va voir si le controller de type HomeController est présent dans le namespace spécifié. S’il n’est pas présent il va alors regarder dans les autres namespaces déclarés dans l’application.

Maintenant il est tout à fait possible de lui spécifier que l’on ne souhaite trouver les controllers que dans le ou les namespaces que l’on a définie dans le fichier global.asax.cs. Pour ce faire il faut spécifier la propriété UseNamespaceFallback à false de la collection DataTokens de notre règle. Voici un exemple :

 public static void RegisterRoutes(RouteCollection routes)
 {
    Route rt = routes.MapRoute("Route 2",
                "{controller}/{action}/{pseudonyme}/{*poubelle}",
                new { controller = "Home", action = "Index", pseudonyme = UrlParameter.Optional },
                new[] { "TestMVCRouting.Controllers" });

    rt.DataTokens["UseNamespaceFallback"] = false;
 }

 

Et voilà le tour est joué ! A noter qui j’ai dû mettre dans une variable le retour de la méthode MapRoute pour pouvoir définir notre propriété.

Dans le prochain article nous verrons comment appliquer des contraintes à nos routes.

Leave a Reply