2010-06-23 15 views
5

Estoy tratando de crear URI que se parecen a algo así: http://hostname/mobile/en/controller/action para móviles O http://hostname/en/controller/action para computadoras de escritorio (no móviles).La ruta siempre va al primer maproute

mesa

Mi ruta actualmente tiene este aspecto (Global.asax.cs)

 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     routes.MapRoute(
      "Mobile", // Route name 
      "mobile/{language}/{controller}/{action}/{id}", // URL with parameters 
      new { language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 
      new { language = @"en|us" } // validation 
     ); 
     routes.MapRoute(
      "Default", // Route name 
      "{language}/{controller}/{action}/{id}", // URL with parameters 
      new { language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 
      new { language = @"en|us" } // validation 
     ); 

El problema se produce cuando intento hacer una return RedirectToAction("Add", "User"); Siempre redirige el navegador de escritorio desde /en/User/List a /mobile/en/User/Add cuando quiero para ir al /en/User/Add. La versión móvil funciona correctamente, pero creo que esto se debe a que la primera ruta "móvil" siempre se ve como la ruta que coincide incluso si no tiene/móvil/al inicio.

estoy tratando de utilizar el mismo controlador para ambas versiones, pero estoy atascado en la que siempre volver a dirigir a la ruta móvil . Esto significa que RedirectToRoute no es perfecto ya que quiero rutas dinámicas.

Gracias por su ayuda.

Respuesta

2

El problema principal es que los valores de ruta que proporciona coinciden con ambas rutas, lo que significa que tomará la primera (que es móvil).

Puede seleccionar manualmente qué ruta usar redirigiendo a las rutas en lugar de las acciones.

return RedirectToRoute("Mobile", new { 
    language = "en", controller = "User", action = "Get", id = 20 
}); 

de móvil o

return RedirectToRoute("Default", new { 
    language = "en", controller = "User", action = "Get", id = 20 
}); 

para su ruta por defecto.

Sin embargo, esto te deja con un nuevo problema: obtener el nombre de la ruta actual. Como se ve en el ejemplo, haciendo referencia a las rutas con nombre es muy posible. Obtener el nombre de la ruta actualmente utilizada parece ser imposible. Usar un truco como mirar el URI actual obviamente no es deseable. Además de ser feo (un truco) también podría llevar a una gran cantidad de duplicación de código.

Sin embargo, existe la posibilidad de añadir valores a las rutas que se pueden obtener fácilmente de su controlador (o vista):

routes.MapRoute(
    "Mobile", // Route name 
    "mobile/{language}/{controller}/{action}/{id}", // URL with parameters 
    new { routeName = "Mobile", language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 
    new { language = @"en|us" } // validation 
); 
routes.MapRoute(
    "Default", // Route name 
    "{language}/{controller}/{action}/{id}", // URL with parameters 
    new { routeName = "Default", language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 
    new { language = @"en|us" } // validation 
); 

Ahora a partir del código puede redirigir a la ruta actual utilizando el valor proporcionado por la propia ruta:

return RedirectToRoute(RouteData.Values["routeName"], new { 
    language = "en", controller = "User", action = "Get", id = 20 
}); 

Ahora bien, si usted quiere hacer esto completamente de fantasía, que puede incluso hacer un método de extensión de esto:

public static class ControllerExtensions { 
    public static RedirectToRouteResult CustomRedirectToRoute(this Controller controller, string controllerName, string actionName, object routevalues) { 
     return CustomRedirectToRoute(controller, controllerName, actionName, new RouteValueDictionary(routevalues)); 
    } 

    public static RedirectToRouteResult CustomRedirectToRoute(this Controller controller, string controllerName, string actionName, RouteValueDictionary routevalues) { 
     routevalues = routevalues ?? new RouteValueDictionary(); 
     routevalues.Add("controller", controllerName); 
     routevalues.Add("action", actionName); 
     return new RedirectToRouteResult(controller.RouteData.Values["routeName"] as string, routevalues); 
    } 
} 

¡Esperamos que esto brinde una buena solución a su problema!

+0

Gracias René que parece exactamente lo que esperaba hacer. ¿Podría decirme dónde es el mejor lugar para poner el método de extensión? – Adrian

+1

Ponga la clase estática ControllerExtensions en cualquier lugar que desee. Y en el controlador que desea usar el redireccionamiento, asegúrese de incluir el espacio de nombres en el que se encuentra la clase de extensiones. Luego, en cualquier lugar de su controlador, puede usar this.CusomRedirectToRoute ("Inicio", "Índice", routeValues); También puede agregar otro método de extensión que ponga null como el valor routeValues ​​si lo desea. –

+0

Si quiere arreglarlo, la última parte de mi comentario puede ser reemplazada por el sistema ordenado y limpio para obtener el nombre de la ruta como se describe en esta publicación: http://stackoverflow.com/questions/363211/how -can-i-get-the-route-name-in-controller-in-asp-net-mvc –

Cuestiones relacionadas