代码之家  ›  专栏  ›  技术社区  ›  Ahmed

在每个URL的末尾添加一个尾随斜杠?

  •  29
  • Ahmed  · 技术社区  · 15 年前

    我这里有点问题。我需要在我正在处理的站点中的每个URL的末尾添加一个尾随斜杠。我定义了站点内的所有链接都有一个尾随斜杠,如下所示:

    <a href="/register/">Register</a>
    

    虽然这样做很好,但还有一个小问题:它与调用RedirectToAction()生成的URL有关。例如:

    return RedirectToAction("Register", "Users");
    

    将导致URL更改为/register,不带尾随斜杠。我修改了我的路由系统:

      routes.MapRoute("register",
                            "register/",
                            new {controller = "Users", action = "Register"}
                );
    

    但所需的尾随斜杠不会自动添加!
    我查过这个 question 而这 question 但是这些完全不同,因为我没有使用任何URL重写库,我只是使用ASP.NET MVC路由系统。
    你们说什么?

    6 回复  |  直到 6 年前
        1
  •  47
  •   Rob    11 年前

    RouteCollection类现在有一个AppendTrailingSlash布尔值,您可以为此行为设置为true。

        2
  •  20
  •   aolde    14 年前

    您可以创建替代 GetVirtualPath 方法。在这个方法中,您向 VirtualPath . 这样地:

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
         VirtualPathData path = base.GetVirtualPath(requestContext, values);
    
         if (path != null)
             path.VirtualPath = path.VirtualPath + "/";
         return path;
    }
    

    为了简洁起见,我发布了 whole example on CodePaste.net

    现在你所要做的就是登记路线 routes.MapRouteTrailingSlash() 而不是 routes.MapRoute() .

    routes.MapRouteTrailingSlash("register",
                                 "register",
                                 new {controller = "Users", action = "Register"}
    );
    

    然后,当 GetVirtualPath() 被称为。哪个 RedirectToAction() 会的。

    更新: 因为codePaste链接已关闭,下面是完整的代码:

    public class TrailingSlashRoute : Route {
        public TrailingSlashRoute(string url, IRouteHandler routeHandler)
            : base(url, routeHandler) {}
    
        public TrailingSlashRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
            : base(url, defaults, routeHandler) {}
    
        public TrailingSlashRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints,
                              IRouteHandler routeHandler)
            : base(url, defaults, constraints, routeHandler) {}
    
        public TrailingSlashRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints,
                              RouteValueDictionary dataTokens, IRouteHandler routeHandler)
            : base(url, defaults, constraints, dataTokens, routeHandler) {}
    
        public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) {
            VirtualPathData path = base.GetVirtualPath(requestContext, values);
    
            if (path != null)
                path.VirtualPath = path.VirtualPath + "/";
            return path;
        }
    }
    
    public static class RouteCollectionExtensions {
        public static void MapRouteTrailingSlash(this RouteCollection routes, string name, string url, object defaults) {
            routes.MapRouteTrailingSlash(name, url, defaults, null);
        }
    
        public static void MapRouteTrailingSlash(this RouteCollection routes, string name, string url, object defaults,
                                             object constraints) {
            if (routes == null)
                throw new ArgumentNullException("routes");
    
            if (url == null)
                throw new ArgumentNullException("url");
    
            var route = new TrailingSlashRoute(url, new MvcRouteHandler())
                        {
                            Defaults = new RouteValueDictionary(defaults),
                            Constraints = new RouteValueDictionary(constraints)
                        };
    
            if (String.IsNullOrEmpty(name))
                routes.Add(route);
            else
                routes.Add(name, route);
        }
    }
    
        3
  •  5
  •   Akaoni    12 年前

    干净的解决方案,代码错误!!

    我遇到的唯一问题是MVC3中主页的双尾随斜杠。

    剃刀实例:

    @Html.ActionLink("Home", "Index", "Home")
    

    链接到:
    http://mysite.com//

    为了解决这个问题,我调整了getvirtualpath覆盖:

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {       
        VirtualPathData path = base.GetVirtualPath(requestContext, values);       
    
        if (path != null && path.VirtualPath != "")       
            path.VirtualPath = path.VirtualPath + "/";       
        return path;       
    }
    
        4
  •  3
  •   RickL    6 年前

    上面的代码错误解决方案是非常好的。我需要一些非常相似的东西,但只针对我的根URL。我知道这可能有问题,但我是这么做的。它在我所有的环境中似乎都能正常工作。我认为它也很有效,因为只有当他们第一次来的时候,它才是我们的主页,没有培训斜杠。这是我试图避免的一个案例。如果这是你想要避免的,这将对你有用。

      public class HomeController : Controller
      {
        public ActionResult Index()
        {
          if (!Request.RawUrl.Contains("Index") && !Request.RawUrl.EndsWith("/"))
            return RedirectToAction("Index", "Home", new { Area = "" });
    

    如果结果证明我需要的不止这些。我可能会使用codingbug提供的代码。在那之前,我喜欢保持简单。

    注意:我指望路由引擎从URL中删除home\index。

        5
  •  1
  •   radu florescu    10 年前

    我知道有更多的赞成的答案,但最好的答案对我的情况不起作用。我需要说我找到了一个更简单的解决方案。

    routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}/{id}/", <-- trailing slash here
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );
    

    在所有情况下,这将充当尾随斜杠“/”。

        6
  •  1
  •   Sustare    8 年前

    这里有一些很好的答案,但是这里有一些MVC控制器代码,说明了如何在一个非常简单的GET中实现它。

        public ActionResult Orders()
        {
            if (!Request.Path.EndsWith("/"))
            {
                return RedirectPermanent(Request.Url.ToString() + "/");
            }
            return View();
        }
    

    希望这能帮助别人。