2012-07-17 2 views
5

di default Ecco il mio percorso di default:MVC redirect per instradare

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

Come sappiamo, quando qualcuno visita www.domain.com/ instradamento del MVC determinerà il controller e l'azione predefinita da eseguire in base al percorso di cui sopra, ma l'URL rimarrà lo stesso. Esiste un modo integrato o elegante per eseguire un reindirizzamento 301 da www.domain.com/ a www.domain.com/uk/{controller}/{action}/ per ogni percorso che utilizza i valori predefiniti?

+0

È possibile eseguire un reindirizzamento dal controller predefinito, ad es. index action – codingbiz

risposta

14

Ho creato un gestore di route personalizzato che esegue il reindirizzamento a livello di percorso. Grazie a Phil Haack.

Ecco il lavoro completo.

gestore percorso di reindirizzamento

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); 
    } 
} 

Redirect gestore 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); 
    } 
} 

estensioni del percorso

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

Avendo tutto questo, posso fare qualcosa di simile mentre mappo rotte in Global.asax.cs.

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

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

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

.. other routes 
+0

Molto accurato, grazie :) – Spikeh

+1

I percorsi dovrebbero essere diretti prima di tutti gli altri percorsi (ex MapRoute)? Funzionerebbe per il vecchio routing della pagina .aspx? foo.aspx ->/foo – Seth

6

Nei miei progetti, solitamente "IndexRedirect" è l'azione predefinita nel mio percorso (il cui URL non sarà mai visibile) che non fa altro che reindirizzare alla pagina indice "reale" (il cui URL sarà sempre visibile).

È possibile creare questa azione in una classe base di tutte le classi controller.

+0

Questa è stata la soluzione migliore! – MEMark

+0

Una nuova idea, vorrei aver pensato a me stesso! – melodiouscode