Pregunta

El sitio web en el que estoy trabajando tiene algunas estructuras de enrutamiento bastante complicadas y estamos experimentando algunas dificultades para trabajar con el motor de enrutamiento para construir URL de la forma en que las necesitamos para construir.

Tenemos una página de resultados de búsqueda que utiliza la coincidencia de patrones basada en RegEx para agrupar varias variables en un solo segmento de ruta (es decir, " www.host.com/ {estructuralParameters} " puede ser el siguiente: " www.host. com / variableA-variableB-variableC " - donde las variables A a C son todas opcionales). Esto nos está funcionando bien después de un poco de trabajo.

El problema que estamos experimentando se resuelve en torno a una característica molesta del método ActionLink: si apuntas al mismo controlador / acción, retendrá los valores de ruta existentes, los quieras o no. Preferimos tener control sobre cómo se ven nuestros enlaces y, en algunos casos, no podemos retener los parámetros existentes. Un ejemplo sería cuando la navegación principal de nuestro sitio conduce a una página de resultados de búsqueda sin parámetros establecidos, una página de búsqueda predeterminada, si lo desea. Digo que esta es una característica molesta porque es una instancia rara del Marco ASP.Net MVC que aparentemente dicta la implementación sin un punto de extensión obvio: ¡preferiríamos no crear código ActionLink personalizado para escribir un enlace de navegación simple en nuestra página maestra!

He visto que algunos dicen que necesita establecer explícitamente dichos parámetros para que sean cadenas vacías, pero cuando lo intentamos, simplemente cambia los parámetros de los valores de ruta a los parámetros de cadena de consulta. No me parece correcto que debamos excluir explícitamente valores que no estamos pasando explícitamente como parámetros al método ActionLink, pero si esta es nuestra única opción, la usaremos. Sin embargo, en la actualidad, si se muestra en la cadena de consulta, es tan inútil como poner los parámetros directamente en la ruta.

Soy consciente de que nuestra estructura de enrutamiento exaspera este problema; probablemente no tendríamos ningún problema si utilizáramos un enfoque más simple (es decir, www.host.com/variableA/variableB/variableC) pero nuestra estructura de URL no es negociable - Fue diseñado para satisfacer necesidades muy específicas relacionadas con la usabilidad, el SEO y el intercambio de enlaces / contenido.

¿Cómo podemos usar Html.ActionLink para generar enlaces a páginas sin recurrir a los datos de ruta actuales (o, si es posible, tener que excluir explícitamente segmentos de ruta) incluso si esos enlaces conducen a los mismos métodos de acción?

Si necesitamos excluir explícitamente segmentos de ruta, ¿cómo podemos evitar que el método represente las rutas como parámetros de cadena de consulta?

Este problema aparentemente pequeño nos está causando una cantidad sorprendente de dolor y agradeceré cualquier ayuda para resolverlo.

EDITAR: según lo solicitado por LukLed, aquí hay una muestra de una llamada de ActionLink:

// I've made it generic, but this should call the Search action of the 
// ItemController, the text and title attribute should say "Link Text" but there
// should be no parameters - or maybe just the defaults, depending on the route.
// 
// Assume that this can be called from *any* page but should not be influenced by
// the current route - some routes will be called from other sections with the same
// structure/parameters.
Html.ActionLink( 
    "Link Text",
    "Search", 
    "Item", 
    new { }, 
    new { title = "Link Text" } 
);
¿Fue útil?

Solución

Establecer los valores de ruta como una cadena nula o vacía cuando se llama a Html.ActionLink o Html.RouteLink (o cualquier método de generación de URL) borrará el "ambiente". valores de ruta.

Por ejemplo, con la ruta del controlador / acción / id MVC estándar, suponga que está en "Inicio / Índice / 123". Si llama a Html.RouteLink (nuevo {id = 456}) , MVC notará el "ambiente". valores de ruta de controller = " Home " y action = " Index " . También notará el valor de ruta ambiental de id = " 123 " pero eso se sobrescribirá con el explícito " 456 " ;. Esto hará que la URL generada sea "Inicio / Índice / 456".

El orden de los parámetros también es importante. Por ejemplo, supongamos que llamó a Html.RouteLink (new {action = " About "}) . El " Acerca de " la acción sobrescribiría el " Índice " actual acción, y el " id " ¡El parámetro se eliminaría por completo! ¿Pero por qué preguntas? Porque una vez que invalidas un segmento de parámetros, todos los segmentos de parámetros después de que se invaliden. En este caso, "acción" fue invalidado por un nuevo valor explícito, por lo que el '' id '', que viene después y no tiene un valor explícito, también se invalida. Por lo tanto, la URL generada sería solo "Inicio / Acerca de" (sin identificación).

En este mismo escenario, si llama a Html.RouteLink (new {action = " "}) , la URL generada sería simplemente " Inicio " porque invalidaste la "acción" con una cadena vacía, y luego eso causó el " id " ser invalidado también porque vino después de la "acción" invalidada.

Otros consejos

Solución en la raíz del problema

Parece que la solución óptima (que no huele a solución alternativa) es la que resuelve el problema donde tiene raíces y eso es en el enrutamiento.

He escrito una clase personalizada de Ruta llamada RouteWithExclusions que puede definir nombres de valores de ruta que deben excluirse / eliminarse al generar URL. El problema es cuando la ruta cae a través de la tabla de rutas y las rutas posteriores no tienen los mismos nombres de valores de ruta ...

Todo el problema se detalla y explica en mi publicación de blog y todo el código también se proporciona allí. Compruébalo, puede ayudarte a resolver este problema de enrutamiento. También he escrito dos métodos adicionales de extensión MapRoute que toman un parámetro adicional.

Si desea un control total del enlace, simplemente cree el enlace usted mismo:

<a href="~/variableA/variableB/<%= Html.Encode(Model.Target) %>">Click Here</a>

Sustituya lo que necesite dentro del atributo href .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top