2012-07-17 201 views
5

這裏是我的默認路由:MVC重定向到默認路由

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

我們知道,當有人訪問www.domain.com/ MVC的路由將決定默認的控制器和執行基於在上面的路線,但網址將保持不變。對於使用默認設置的每條路線,是否有內置或優雅的方式來執行從www.domain.com/到www.domain.com/uk/{controller}/{action}/的301重定向?

+0

您可以從默認控制器執行重定向,例如,指數行動 – codingbiz 2012-07-17 09:20:14

回答

14

我已經創建了一個自定義的路由處理程序,在路由級別進行重定向。感謝Phil Haack

這是完整的工作。

重定向路由處理

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

重定向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); 
    } 
} 

路線擴展

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

擁有所有這些,我可以在Global.asax.cs中映射路由時做類似的事情。

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

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

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

.. other routes 
+0

非常全面,謝謝:) – Spikeh 2012-07-17 12:01:48

+1

routes.Redirect應該在所有其他路線(前MapRoute)之前?這是否適用於舊的.aspx頁面路由? foo.aspx - >/foo – Seth 2013-04-16 16:36:02

6

在我的項目中,我通常將「IndexRedirect」作爲路由中的默認動作(其URL永遠不可見),除了重定向到「真實」索引頁面(其URL始終可見)之外,它什麼都不做。

您可以在所有控制器類的基類中創建此操作。

+0

這是最好的解決方案! – MEMark 2013-09-18 12:52:23

+0

一個新奇的想法,希望我自己想到了! – melodiouscode 2015-11-17 20:05:56