tag route parameter net mvc for data asp all asp.net-mvc routing actionlink

route - ¿Cómo puedo evitar que ASP.Net MVC Html.ActionLink use los valores de ruta existentes?



href mvc razor (3)

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

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

Sustituya lo que necesite dentro del atributo href .

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 manera que necesitamos que se construyan.

Tenemos una página de resultados de búsqueda que usa la coincidencia de patrones basada en RegEx para agrupar varias variables en un único segmento de ruta (es decir, "www.host.com/{structuralParameters}" puede ser la siguiente: "www.host.com/variableA-variableB- variableC "- donde las variables A a C son todas opcionales). Esto está funcionando bien para nosotros 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 apunta al mismo controlador / acción, retendrá los valores de ruta existentes, ya sea que los quiera o no. Preferimos tener control sobre cómo se ven nuestros enlaces y, en algunos casos, no se pueden conservar 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 rara instancia de ASP.Net MVC Framework que aparentemente impone la implementación sin un punto de extensión obvio. Preferiríamos no crear un código ActionLink personalizado para escribir un simple enlace de navegación en nuestra página maestra.

He visto a algunos decir que necesita establecer explícitamente tales parámetros para que sean cadenas vacías, pero cuando intentamos esto, simplemente cambia los parámetros de los valores de ruta a los parámetros de cadena de consulta. No me parece correcto que se nos requiera 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, lo usaremos. Sin embargo, actualmente, si se muestra en la cadena de consulta, nos resulta 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, era diseñado para satisfacer necesidades muy específicas relacionadas con la usabilidad, SEO y el intercambio de enlaces / contenido.

¿Cómo podemos utilizar Html.ActionLink para generar enlaces a páginas sin recurrir a los datos de ruta actuales (o, si es posible, la necesidad de 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 sorprendente cantidad de dolor y estaremos agradecidos por cualquier ayuda para resolverlo.

EDITAR: Tal como lo solicitó LukLed, aquí hay una llamada de muestra 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" } );


Solución en la raíz del problema

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

RouteWithExclusions una clase de Route personalizada llamada RouteWithExclusions que puede definir nombres de valores de ruta que deberían excluirse / eliminarse al generar URL. El problema es cuando el enrutamiento cae a través de la tabla de rutas y las rutas subsiguientes no tienen los mismos nombres de valor de ruta ...

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


Establecer valores de ruta para que sean nulos o una cadena vacía al llamar a Html.ActionLink o Html.RouteLink (o cualquier método de generación de URL) eliminará los valores de ruta "ambiente".

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

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

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