Digamos que tiene un método de acción para mostrar los productos en un carrito de la compraCómo prevenir Url.RouteUrl (...) de heredar los valores de ruta de la petición actual
// ProductsController.cs
public ActionMethod Index(string gender) {
// get all products for the gender
}
Por otra parte, en un mástil que es que aparece en cada página que está utilizando Url.RouteUrl
para crear enlaces HREF a otras páginas en el sitio:
<a href="<%= Url.RouteUrl("testimonials-route", new { }) %>" All Testimonials </a>
Este testimonials-route
se define en global.ascx
por la primera ruta a continuación. Observe que la llamada anterior al RouteUrl
no proporciona un gender
, pero la ruta se define con un valor predeterminado de 'neutral', por lo que esperaríamos que se llamara Testimonials.Index ("neutral").
routes.MapRoute(
"testimonials-route",
"testimonials/{gender}",
new { controller = "Testimonials", action = "Index", gender = "neutral" },
new { gender = "(men|women|neutral)" }
);
routes.MapRoute(
"products-route",
"products/{gender}",
new { controller = "Products", action = "Index", gender = (string)null },
new { gender = "(men|women|neutral)" }
);
Si alguien visita la página /products/women
obtenemos un HREF a /testimonials/women
Si alguien visita la página /products
entonces tenemos un HREF vacía (la llamada a RouteUrl devuelve un valor nulo).
Pero eso no tiene sentido, ¿verdad? testimonials-route
se supone que es el predeterminado para nosotros 'neutral'
si no proporcionamos un valor de ruta para el mismo?
lo que resulta que está sucediendo es que Url.RouteUrl(routeName, routeValues)
extensión ayudante primero buscará en su parámetro routeValues
por un valor gender
ruta y si no lo encuentra en ese diccionario que se verá en la URL actual que estamos en (recuerde que Url es un objeto UrlHelper que tiene el contexto de la solicitud actual disponible).
Esto tiene un posible efecto agradable de darnos un enlace a los testimonios de los hombres si estamos en una página de productos para hombres, pero eso probablemente no es lo que queremos si no hemos pasado un valor en la llamada RouteUrl
, y explícitamente se especificó 'neutral' como predeterminado en el archivo global.asax.cs
.
En el caso en que visitamos /products/
activamos la ruta 'products-route'
y se llamó al método Products(null)
. La llamada al Url.RouteUrl()
en realidad hereda ESTE valor nulo para gender
cuando estamos creando una URL usando testimonials-route
. Aunque hemos especificado un valor predeterminado para gender
en 'testimionials-route
', todavía utiliza este valor nulo que hace que la ruta falle y RouteUrl
devuelve nulo. [nota: la ruta falla porque tenemos una restricción en (hombres | mujeres | neutro) y nulo no cabe eso]
En realidad se pone más atemorizante - en ese 'controlador' y 'acción' se puede heredar de la misma manera. Esto puede conducir a que se generen direcciones URL completamente equivocadas en el controlador incluso cuando se llama a RouteUrl (...) con un nombre de ruta explícito que tiene un controlador predeterminado.
En este caso, una vez que lo ha resuelto, puede solucionarlo con bastante facilidad de muchas maneras, pero en otros casos podría causar un comportamiento peligroso. Esto puede ser por diseño, pero definitivamente da miedo.
agregando un bounty un año y medio después de la pregunta original porque (a) me gustaría saber si el marco ahora lo hace por mí y (b) tengo mucha curiosidad por qué esto solo tiene 2 votos positivos. pensé que sería un problema común, ¡así que me pregunto si estoy haciendo algo mal! –
esto estaba pateando mi botín, ya que la etiqueta {domain} carecía de un valor, pero que el sistema debería proporcionar automáticamente. Una vez que cambié esto, funcionó. –
¿por qué no simplemente llama a RenderUrl como: ' "' - entonces, nada se sobrescribe . – Gerwald