2012-07-17 34 views
5

Aquí está mi ruta por defecto:MVC redirigir a los valores predeterminados ruta

routes.MapRouteLowercase(
       "Default", 
       "{country}/{controller}/{action}/{id}", 
       new { 
        country = "uk", 
        controller = "Home", 
        action = "Index", 
        id = UrlParameter.Optional 
       }, 
       new[] { "Presentation.Controllers" } 
       ); 

Como sabemos, cuando alguien visita www.domain.com/ enrutamiento de MVC determinará el controlador y la acción por defecto para ejecutar en base a la ruta anterior, pero la URL seguirá siendo la misma. ¿Existe una forma integrada o elegante de realizar un redireccionamiento 301 desde www.domain.com/ a www.domain.com/uk/{controller}/{action}/ para cada ruta que utiliza valores predeterminados?

+0

Podría hacer una redirección desde su controlador predeterminado, p. index action – codingbiz

Respuesta

14

He creado un controlador de ruta personalizado que hace la redirección en el nivel de la ruta. Gracias a Phil Haack.

Aquí está el trabajo completo.

controlador de ruta de redireccionamiento

public class RedirectRouteHandler : IRouteHandler 
{ 
    private string _redirectUrl; 

    public RedirectRouteHandler(string redirectUrl) 
    { 
     _redirectUrl = redirectUrl; 
    } 

    public IHttpHandler GetHttpHandler(RequestContext requestContext) 
    { 
     if (_redirectUrl.StartsWith("~/")) 
     { 
      string virtualPath = _redirectUrl.Substring(2); 
      Route route = new Route(virtualPath, null); 
      var vpd = route.GetVirtualPath(requestContext, 
       requestContext.RouteData.Values); 
      if (vpd != null) 
      { 
       _redirectUrl = "~/" + vpd.VirtualPath; 
      } 
     } 

     return new RedirectHandler(_redirectUrl, false); 
    } 
} 

redirección controlador HTTP

public class RedirectHandler : IHttpHandler 
{ 
    private readonly string _redirectUrl; 

    public RedirectHandler(string redirectUrl, bool isReusable) 
    { 
     _redirectUrl = redirectUrl; 
     IsReusable = isReusable; 
    } 

    public bool IsReusable { get; private set; } 

    public void ProcessRequest(HttpContext context) 
    { 
     context.Response.Status = "301 Moved Permanently"; 
     context.Response.StatusCode = 301; 
     context.Response.AddHeader("Location", _redirectUrl); 
    } 
} 

extensiones de ruta

public static class RouteExtensions 
{ 
    public static void Redirect(this RouteCollection routes, string url, string redirectUrl) 
    { 
     routes.Add(new Route(url, new RedirectRouteHandler(redirectUrl))); 
    } 
} 

Al tener todo esto, puedo hacer algo como esto al mapear rutas en Global.asax.cs.

routes.Redirect("", "/uk/Home/Index"); 

routes.Redirect("uk", "/uk/Home/Index"); 

routes.Redirect("uk/Home", "/uk/Home/Index"); 

.. other routes 
+0

Muy minucioso, gracias :) – Spikeh

+1

¿Deberían las rutas.Redirect ir antes que todas las demás rutas (por ejemplo, MapRoute)? ¿Esto funcionaría para el enrutamiento de páginas antiguas de .aspx? foo.aspx ->/foo – Seth

6

En mis proyectos, generalmente tengo "IndexRedirect" como acción predeterminada en mi ruta (cuya URL nunca será visible) que no hace más que redirigir a la página de índice "real" (cuya URL siempre estará visible).

Puede crear esta acción en una clase base de todas sus clases de controlador.

+0

¡Esta fue la mejor solución! – MEMark

+0

Una idea nueva, ¡ojalá hubiera pensado en mí! – melodiouscode

Cuestiones relacionadas