/ / mvcSitemap et routes multiples - asp.net-mvc, asp.net-mvc-routing, mvcsitemapprovider, mvcsitemap

mvcSitemap et plusieurs routes - asp.net-mvc, asp.net-mvc-routing, mvcsitemapprovider, mvcsitemap

J'essaie d'utiliser le sitemap de MVC pour créer unfil d'Ariane pour mon application. J'ai plusieurs itinéraires dans le contrôleur d'utilisateur et j'ai besoin de préserver le fil d'Ariane pour chacun. Comment mvcSiteMap associe-t-il chaque nœud à la route?

J'ai les itinéraires possibles suivants dans un utilisateur:

/ Utilisateur / {action} / {IDutilisateur}

/ User / {groupid} / {action} / {userid}

Je voudrais les chemins de navigation suivants:

Racine d'application> Utilisateurs> {Nom d'utilisateur}> {Action}

Racine de l'application> Gestion des groupes> {Nom du groupe}> {Nom d'utilisateur}> {Action}

Le premier des itinéraires ci-dessus est simpleassez et je décore le contrôleur Details avec [SiteMapTitle ("Mail")] pour afficher l'attribut Mail d'objets au lieu de "Détails" et le Edit est décoré avec [SiteMapTitle ("Mail", Target = AttributeTarget.ParentNode)] pour préserver le adresse e-mail lors de l'édition.

Mais je ne peux pas comprendre comment faire tout celalors de l'utilisation du deuxième itinéraire. Le fil d'Ariane ne affiche rien du tout. La section Utilisateurs de la section Groupe semble ne rien faire. Quel est le meilleur moyen d'y parvenir?

Mvc.Sitemap:

    <mvcSiteMapNode title="User Management" controller="User" action="Index">
<mvcSiteMapNode title="Details" action="Details" controller="User" preservedRouteParameters="id">
<mvcSiteMapNode title="Edit" action="Edit" controller="User" preservedRouteParameters="id"/>
</mvcSiteMapNode>
</mvcSiteMapNode>

<mvcSiteMapNode title="Group Management" controller="Group" action="Index">
<mvcSiteMapNode title="Details" action="Details" controller="Group" preservedRouteParameters="id">
<mvcSiteMapNode title="Edit" action="Edit" controller="Group" preservedRouteParameters="id"/>

<mvcSiteMapNode title="Users" controller="User" action="Index" preservedRouteParameters="groupid">
<mvcSiteMapNode title="Details" action="Details" controller="User" preservedRouteParameters="id, groupid">
<mvcSiteMapNode title="Edit" action="Edit" controller="User" preservedRouteParameters="id, groupid"/>
<mvcSiteMapNode title="Manage" action="Manage" controller="User" preservedRouteParameters="id, groupid"/>
</mvcSiteMapNode>
</mvcSiteMapNode>


</mvcSiteMapNode>
<mvcSiteMapNode title="New" action="Create" controller="Group" />
</mvcSiteMapNode>
...
</mvcSiteMapNode>

Itinéraires:

routes.MapRoute("ByGroup", "User/{groupid}/{action}/{id}",
new { controller = "User", action = "Index", id = UrlParameter.Optional }, new { groupid = new GuidConstraint() });

routes.MapRoute("ByGroup2", "User/{groupid}/{action}/{id}",
new { controller = "User", action = "Index", id = UrlParameter.Optional, groupid = UrlParameter.Optional }, new { groupid = new GuidConstraint() });


routes.MapRoute("User", "User/{action}/{id}",
new { controller = "User", action = "Index", id = UrlParameter.Optional });


routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });

Réponses:

2 pour la réponse № 1

Nœuds:

<mvcSiteMapNode title="User Management" controller="User" action="Index" route="Default">
<mvcSiteMapNode title="Details" action="Details" controller="User" route="Default" preservedRouteParameters="id">
<mvcSiteMapNode title="Edit" action="Edit" controller="User" route="Default" preservedRouteParameters="id"/>
</mvcSiteMapNode>
</mvcSiteMapNode>

<mvcSiteMapNode title="Group Management" controller="Group" action="Index">
<mvcSiteMapNode title="Details" action="Details" controller="Group" preservedRouteParameters="groupid">
<mvcSiteMapNode title="Edit" action="Edit" controller="Group" preservedRouteParameters="groupid"/>

<mvcSiteMapNode title="Users" controller="User" action="Index" route="ByGroup" preservedRouteParameters="groupid">
<mvcSiteMapNode title="Details" action="Details" controller="User" route="ByGroup" preservedRouteParameters="id, groupid">
<mvcSiteMapNode title="Edit" action="Edit" controller="User" route="ByGroup" preservedRouteParameters="id, groupid"/>
<mvcSiteMapNode title="Manage" action="Manage" controller="User" route="ByGroup" preservedRouteParameters="id, groupid"/>
</mvcSiteMapNode>
</mvcSiteMapNode>

</mvcSiteMapNode>
<mvcSiteMapNode title="New" action="Create" controller="Group" />
</mvcSiteMapNode>

Itinéraires:

routes.MapRoute(
name: "Group",
url: "Group/{action}/{groupid}",
defaults: new { controller = "Group", action = "Index", groupid = UrlParameter.Optional });

routes.MapRoute(
name: "ByGroup",
url: "User/{groupid}/{action}/{id}",
defaults: new { controller = "User", action = "Index", id = UrlParameter.Optional },
constraints: new { groupid = new GuidConstraint() });

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

Explication

Vous avez défini 2 segments facultatifs sur le ByGroup2 route, ce qui n'est pas autorisé. Un segment facultatif doit se trouver à l'extrême droite de l'URL et ne peut pas être suivi d'un segment obligatoire. Cela est probablement à l'origine des problèmes.

En outre, je ne vois pas de véritable objectif pour le ByGroup2 route.

/User/131f89da-0dca-40f0-bc99-41559d13fc7f/Edit/123 - matches ByGroup
/User/131f89da-0dca-40f0-bc99-41559d13fc7f/Index - matches ByGroup
/User/Edit/123 - matches User
/User/Index - matches User

Je ne peux pas penser à un cas qui va correspondre ByGroup2. Mais si ça Est-ce que correspond, vos paramètres seront placés dans des clés de route différentes que si elle correspond à la User route, ce qui pourrait être des choses déroutantes.

Aussi votre User route ne semble pas ajouter quoi que ce soit sur le Default route. Ainsi, la configuration de votre route pourrait ressembler à ceci et faire exactement la même chose (moins la confusion des positions de valeur de route, ce qui pourrait vous causer des problèmes).

routes.MapRoute("ByGroup", "User/{groupid}/{action}/{id}",
new { controller = "User", action = "Index", id = UrlParameter.Optional }, new { groupid = new GuidConstraint() });

routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });

Et puis la correspondance ressemblerait à ceci.

/User/131f89da-0dca-40f0-bc99-41559d13fc7f/Edit/123 - matches ByGroup
/User/131f89da-0dca-40f0-bc99-41559d13fc7f/Index - matches ByGroup
/User/Edit/123 - matches Default
/User/Index - matches Default

Cependant, vous avez également un problème avec vos préservésRouteParameters.

<mvcSiteMapNode title="Details" action="Details" controller="Group" preservedRouteParameters="id">
<mvcSiteMapNode title="Edit" action="Edit" controller="Group" preservedRouteParameters="id"/>

<mvcSiteMapNode title="Users" controller="User" action="Index" preservedRouteParameters="groupid">
<mvcSiteMapNode title="Details" action="Details" controller="User" preservedRouteParameters="id, groupid">
<mvcSiteMapNode title="Edit" action="Edit" controller="User" preservedRouteParameters="id, groupid"/>
<mvcSiteMapNode title="Manage" action="Manage" controller="User" preservedRouteParameters="id, groupid"/>
</mvcSiteMapNode>
</mvcSiteMapNode>
</mvcSiteMapNode>
</mvcSiteMapNode>

Pour que preserveRouteParameters corresponde à plusieurs niveaux, toutes les valeurs de route personnalisées (dans ce cas, id et groupid) du ancêtre les nœuds doivent être fournis. De plus, ils doivent avoir le même sens. Pour que cela fonctionne, id doit toujours faire référence à la même entité tout au long des nœuds et doit être inclus dans chaque lien, quelle que soit sa profondeur. Vous devez choisir un différent clé de route pour l'entité Groupe que pour l'entité Utilisateur.

Pour nettoyer cela, vous pouvez modifier les itinérairesplus de temps pour mettre toutes les informations dans l'itinéraire requis. Vous avez déjà presque terminé votre chemin. Il vous suffit de corriger l'id des nœuds du groupe.

routes.MapRoute(
name: "Group",
url: "Group/{action}/{groupid}",
defaults: new { controller = "Group", action = "Index", groupid = UrlParameter.Optional });

routes.MapRoute(
name: "ByGroup",
url: "User/{groupid}/{action}/{id}",
defaults: new { controller = "User", action = "Index", id = UrlParameter.Optional },
constraints: new { groupid = new GuidConstraint() });

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

Et des nœuds:

<mvcSiteMapNode title="Details" action="Details" controller="Group" preservedRouteParameters="groupid">
<mvcSiteMapNode title="Edit" action="Edit" controller="Group" preservedRouteParameters="groupid"/>

<mvcSiteMapNode title="Users" controller="User" action="Index"  route="ByGroup" preservedRouteParameters="groupid">
<mvcSiteMapNode title="Details" action="Details" controller="User" route="ByGroup" preservedRouteParameters="id, groupid">
<mvcSiteMapNode title="Edit" action="Edit" controller="User" route="ByGroup" preservedRouteParameters="id, groupid"/>
<mvcSiteMapNode title="Manage" action="Manage" controller="User" route="ByGroup" preservedRouteParameters="id, groupid"/>
</mvcSiteMapNode>

Notez que chaque itinéraire situé en dessous de la /Group/Index noeud a maintenant un groupid, et le groupid clé fait toujours référence à la même entité?

En outre, pour nous assurer que nous ne faisons correspondre que lesroute, nous le spécifions explicitement. Si nous ne l’avions pas fait, les nœuds d’utilisateur seraient ambigus et vous obtiendriez le mauvais chemin de navigation (le premier nœud qui correspond gagne).

route="ByGroup"

Avec la configuration ci-dessus, vous auriez besoin de créer les liens vers le Users, Users/Details, Users/Edit, et Users/Manage qui incluent le courant groupid (et bien sûr, l'identifiant de l'utilisateur actuel).

@Html.ActionLink("Edit User", "Edit", "User", new { id = <userid>, groupid = <groupid> }, null)

Ensuite, lorsque vous accédez au lien "Modifier l'utilisateur", l'ID de groupe sera dans la demande en cours, qui le transmettra à la Users/Details nœud, Group/Edit noeud, et Group/Details noeud lors de la résolution des URL afin que vous puissiez revenir à ces emplacements via le fil d'Ariane.

Voir l'exemple Forcing-A-Match-2-Levels dans le téléchargement de code de cet article pour un autre exemple.

La section utilisateur qui n’a pas de groupe correspondra à la Default route, et indiquera le chemin de navigation approprié lors de la création de l'URL sans le groupid.

Nous spécifions donc explicitement la route par défaut:

route="Default"

Et construisez l'URL comme:

@Html.ActionLink("Edit User", "Edit", "User", new { id = <userid> }, null)