/ / mvcSitemap y múltiples rutas - asp.net-mvc, asp.net-mvc-routing, mvcsitemapprovider, mvcsitemap

mvcSitemap y rutas múltiples: asp.net-mvc, asp.net-mvc-routing, mvcsitemapprovider, mvcsitemap

Estoy tratando de usar el mapa del sitio MVC para crear unSendero de migajas para mi aplicación. Tengo varias rutas hacia el controlador de usuario y necesito preservar las rutas de navegación para cada uno. ¿Cómo mapea mvcSiteMap cada nodo a la ruta?

Tengo las siguientes rutas posibles en un usuario:

/ User / {action} / {userid}

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

Me gustaría los siguientes senderos de migas de pan respectivamente:

Raíz de la aplicación> Usuarios> {Nombre de usuario}> {Acción}

Raíz de la aplicación> Gestión de grupos> {Nombre de grupo}> {Nombre de usuario}> {Acción}

La primera de las rutas anteriores es sencilla.basta y decoro el controlador de Detalles con [SiteMapTitle ("Mail")] para mostrar el atributo Mail de los objetos en lugar de "Details" y la Edición está decorada con [SiteMapTitle ("Mail", Target = AttributeTarget.ParentNode)] para preservar el Dirección de correo electrónico al editar.

Pero, no puedo averiguar cómo hacer todo estoAl utilizar la segunda ruta. El rastro de ruta no muestra nada en absoluto. La sección Usuarios en la sección Grupo parece no hacer nada. ¿Cuál es la mejor manera de lograrlo?

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>

Rutas:

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 });

Respuestas

2 para la respuesta № 1

Nodos:

<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>

Rutas:

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 }
);

Explicación

Has definido 2 segmentos opcionales en el ByGroup2 ruta, que no está permitida. Un segmento opcional debe estar en la posición más a la derecha de la URL y no puede ir seguido de un segmento requerido. Esto probablemente esté causando problemas.

Además, no veo ningún propósito real para el ByGroup2 ruta.

/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

No puedo pensar en un caso que coincida ByGroup2. Pero si hace coinciden, sus parámetros se colocarán en diferentes claves de ruta que si coinciden con las User Ruta, lo que podría ser algo confuso.

También tu User La ruta no parece añadir nada sobre el Default ruta. Por lo tanto, la configuración de su ruta podría verse así y hacer exactamente lo mismo (menos la confusión de las posiciones de valor de ruta, lo que podría estar causándole problemas).

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 });

Y luego el emparejamiento se vería así.

/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

Sin embargo, también tiene un problema con los preservRouteParameters.

<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>

Para preserveRouteParameters para que coincida con varios niveles, todos los valores de ruta personalizados (en este caso id y groupid) del antepasado Los nodos deben ser suministrados. Además, deben tener el mismo significado. Para que esto funcione, id Siempre debe referirse a la misma entidad a lo largo de los nodos, y debe incluirse en cada enlace, sin importar cuán profundo sea. Debes elegir un diferente clave de ruta para la entidad de grupo que para la entidad de usuario.

Para limpiar esto, podrías alterar las rutas uno.más tiempo para poner toda la información en la ruta que se requiere. Ya casi está en el camino, solo necesita corregir la identificación de los nodos del Grupo.

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 }
);

Y nodos

<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>

Tenga en cuenta que todas las rutas que están por debajo de la /Group/Index nodo ahora tiene una groupid, y el groupid clave siempre se refiere a la misma entidad?

Además, para asegurarnos de que solo coincidimos con lo pertinente.Ruta, lo especificamos explícitamente. Si no lo hiciéramos, los nodos del usuario serían ambiguos, por lo que obtendremos el rastro de ruta de navegación incorrecto (el primer nodo que coincida con las victorias).

route="ByGroup"

Con la configuración anterior, necesitaría construir los enlaces a la Users, Users/Details, Users/Edity Users/Manage que incluyen la corriente groupid (y por supuesto, la identificación de usuario actual).

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

Luego, cuando navegue hasta el enlace "Editar usuario", el groupid estará en la solicitud actual, que lo enviará a la Users/Details nodo, Group/Edit nodo, y Group/Details Nodo al resolver las URL para que pueda navegar de regreso a esas ubicaciones a través de la ruta de navegación.

Vea el ejemplo de Forcing-A-Match-2-Levels en la descarga del código de este articulo para otro ejemplo.

La sección de usuario que no tiene un grupo coincidirá con la Default ruta, y mostrará el rastro de ruta de navegación apropiado al crear la URL sin el groupid.

Así que especificamos explícitamente la ruta por defecto:

route="Default"

Y construir la URL como:

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