asp.net-mvc
Le routage
Recherche…
Introduction
Le routage est la manière dont ASP.NET MVC associe un URI à une action. Le module de routage est chargé de mapper les requêtes du navigateur entrant vers des actions de contrôleur MVC particulières.
MVC 5 prend en charge un nouveau type de routage, appelé routage d'attribut. Comme son nom l'indique, le routage d'attribut utilise des attributs pour définir des itinéraires. Le routage d'attributs vous permet de mieux contrôler les URI de votre application Web.
Routage personnalisé
Le routage personnalisé fournit un besoin spécialisé de routage pour gérer des demandes entrantes spécifiques.
Pour définir des itinéraires personnalisés, gardez à l'esprit que l'ordre des itinéraires que vous ajoutez à la table de routage est important.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// this is an advanced custom route
// you can define custom URL with custom parameter(s) point to certain action method
routes.MapRoute(
"CustomEntry", // Route name
"Custom/{entryId}", // Route pattern
new { controller = "Custom", action = "Entry" } // Default values for defined parameters above
);
// this is a basic custom route
// any custom routes take place on top before default route
routes.MapRoute(
"CustomRoute", // Route name
"Custom/{controller}/{action}/{id}", // Route pattern
new { controller = "Custom", action = "Index", id = UrlParameter.Optional } // Default values for defined parameters above
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // Route pattern
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Default values for defined parameters above
);
}
controller
noms de controller
et d' action
sont réservés. Par défaut, MVC mappe {controller}
partie de l'URL sur la classe <controller>Controller
, puis recherche une méthode portant le nom <action>
sans ajouter de suffixe.
Bien que cela puisse être tentant de créer une famille de routes en utilisant {controller}/{action}/{parameter}
template, sachez que cela vous permet de révéler la structure de votre application et de rendre les URL quelque peu fragiles. achemine et rompt les liens enregistrés par l'utilisateur.
Préférer un paramétrage de route explicite:
routes.MapRoute(
"CustomRoute", // Route name
"Custom/Index/{id}", // Route pattern
new { controller = "Custom", action = nameof(CustomController.Index), id = UrlParameter.Optional }
);
(vous ne pouvez pas utiliser le nameof
opérateur pour le nom du contrôleur car il aura un suffixe supplémentaire Controller
) qui doit être omis lors de la définition du nom du contrôleur dans l'itinéraire.
Ajout d'un itinéraire personnalisé dans Mvc
L'utilisateur peut ajouter un itinéraire personnalisé, mappant une URL à une action spécifique dans un contrôleur. Ceci est utilisé pour l'optimisation des moteurs de recherche et rend les URL lisibles.
routes.MapRoute(
name: "AboutUsAspx", // Route name
url: "AboutUs.aspx", // URL with parameters
defaults: new { controller = "Home", action = "AboutUs", id = UrlParameter.Optional } // Parameter defaults
);
Routage des attributs dans MVC
Avec les méthodes classiques de définition de route, les frameworks MVC WEB API 2 puis MVC 5 ont introduit le Attribute routing
:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// This enables attribute routing and must go before other routes are added to the routing table.
// This makes attribute routes have higher priority
routes.MapMvcAttributeRoutes();
}
}
Pour les routes avec le même préfixe dans un contrôleur, vous pouvez définir un préfixe commun pour des méthodes d'action complètes à l'intérieur du contrôleur à l'aide de l'attribut RoutePrefix
.
[RoutePrefix("Custom")]
public class CustomController : Controller
{
[Route("Index")]
public ActionResult Index()
{
...
}
}
RoutePrefix
est facultatif et définit la partie de l'URL préfixée par toutes les actions du contrôleur.
Si vous disposez de plusieurs routes, vous pouvez définir une route par défaut en capturant l'action en tant que paramètre, puis l'appliquer à la totalité du contrôleur, sauf si un attribut Route
spécifique est défini sur certaines méthodes d'action qui remplacent la route par défaut.
[RoutePrefix("Custom")]
[Route("{action=index}")]
public class CustomController : Controller
{
public ActionResult Index()
{
...
}
public ActionResult Detail()
{
...
}
}
Bases du routage
Lorsque vous demandez l'url yourSite/Home/Index
via un navigateur, le module de routage dirigera la requête vers la méthode d'action Index
de la classe HomeController
. Comment savoir comment envoyer la demande à la méthode spécifique de cette classe spécifique? il vient le RouteTable.
Chaque application possède une table de routage dans laquelle elle stocke le modèle de route et des informations sur la destination de la demande. Ainsi, lorsque vous créez votre application mvc, une route par défaut est déjà enregistrée dans la table de routage. Vous pouvez voir cela dans la classe RouteConfig.cs
.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
Vous pouvez voir que l'entrée a un nom et un modèle. Le modèle est le modèle de route à vérifier lorsqu'une demande entre en jeu. Le modèle par défaut a Home
comme valeur du segment d'URL du contrôleur et Index
comme valeur du segment d'action. Cela signifie que si vous ne transmettez pas explicitement un nom de contrôleur et une action dans votre requête, il utilisera ces valeurs par défaut. C'est la raison pour laquelle vous obtenez le même résultat lorsque vous accédez à votre yourSite/Home/Index
et à votre yourSite
Vous avez peut-être remarqué que nous avons un paramètre appelé id comme dernier segment de notre modèle de route. Mais dans les valeurs par défaut, nous spécifions que c'est facultatif. C’est la raison pour laquelle nous n’avons pas eu besoin de spécifier la valeur d’ID dans l’url que nous avons essayée.
Maintenant, retournez à la méthode d’action Index dans HomeController et ajoutez un paramètre à celle-ci.
public ActionResult Index(int id)
{
return View();
}
Mettez maintenant un point de repère visuel en studio dans cette méthode. Exécutez votre projet et accédez à votre yourSite/Home/Index/999
dans votre navigateur. Le point d'arrêt sera touché et vous devriez pouvoir voir que la valeur 999 est maintenant disponible dans le paramètre id
.
Création d'un second motif de route
Disons que nous voudrions qu'il soit configuré de telle sorte que la même méthode d'action soit appelée pour un modèle de route différent. Nous pouvons le faire en ajoutant une nouvelle définition de route à la table de routage.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// New custom route definition added
routes.MapRoute("MySpecificRoute",
"Important/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
//Default catch all normal route definition
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
La nouvelle définition que j'ai ajoutée a un motif Important/{id}
où id est à nouveau facultatif. Cela signifie que lorsque vous demandez votre yourSiteName\Important
ou votre yourSiteName\Important\888
, il sera envoyé à l'action Index de HomeController.
Enregistrement de l'ordre de définition de l'itinéraire
L'ordre d'enregistrement des itinéraires est important. Vous devez toujours enregistrer les modèles de route spécifiques avant la route par défaut générique.
Catch-all route
Supposons que nous voulons avoir un itinéraire qui autorise un nombre non lié de segments comme celui-ci:
- http://example.com/Products/ (voir tous les produits)
- http://example.com/Products/IT
- http://example.com/Products/IT/Laptops
- http://example.com/Products/IT/Laptops/Ultrabook
- http://example.com/Products/IT/Laptops/Ultrabook/Asus
- etc.
Nous devrions ajouter une route, normalement à la fin de la table de routage, car cela intercepterait probablement toutes les demandes, comme ceci:
routes.MapRoute("Final", "Route/{*segments}",
new { controller = "Product", action = "View" });
Dans le contrôleur, une action qui pourrait gérer cela pourrait être:
public void ActionResult View(string[] segments /* <- the name of the parameter must match the name of the route parameter */)
{
// use the segments to obtain information about the product or category and produce data to the user
// ...
}
Route Catch-All pour activer le routage côté client
Il est recommandé de coder l’état de l’application Single Page (SPA) dans url:
my-app.com/admin-spa/users/edit/id123
Cela permet de sauvegarder et de partager l'état de l'application.
Lorsque l'utilisateur place une URL dans la barre d'adresse du navigateur et que les hits entrent, le serveur doit ignorer la partie côté client de l'URL demandée. Si vous diffusez votre SPA en tant que vue Razor rendue (résultat de l’action d’appel du contrôleur) plutôt qu’un fichier HTML statique, vous pouvez utiliser un itinéraire fourre-tout:
public class AdminSpaController
{
[Route("~/admin-spa/{clienSidePart*}")]
ActionResult AdminSpa()
{
...
}
}
Dans ce cas, le serveur ne renvoie que SPA et s’initialise ensuite en fonction de la route. Cette approche est plus flexible car elle ne dépend pas du module de réécriture d'url .
Routage des attributs dans les zones
Pour utiliser le routage d'attribut dans les zones, les zones d'enregistrement et les [RouteArea(...)]
sont requises.
Dans RouteConfig.cs
:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
}
}
Dans une définition de routage d'attribut de contrôleur de zone d'échantillon:
[RouteArea("AreaName", AreaPrefix = "AreaName")]
[RoutePrefix("SampleAreaController")]
public class SampleAreaController : Controller
{
[Route("Index")]
public ActionResult Index()
{
return View();
}
}
Pour utiliser les liens Url.Action
dans les zones:
@Url.Action("Index", "SampleAreaController", new { area = "AreaName" })