【问题标题】:Add a trailing slash at the end of each url?在每个网址的末尾添加一个斜杠?
【发布时间】:2010-11-25 23:54:19
【问题描述】:

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

<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 路由系统。
那你们怎么说呢?

【问题讨论】:

  • 对于如何为 ASP.NET Core 执行此操作感兴趣的任何人,请使用 services.Configure&lt;RouteOptions&gt;(routeOptions =&gt; { routeOptions.AppendTrailingSlash = true;};,其中 servicesIServiceCollection
  • 要访问RouteOptions,请务必访问using Microsoft.AspNetCore.Routing;

标签: asp.net-mvc url-routing


【解决方案1】:

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

【讨论】:

  • AppendTrailingSlash不重写路由。
【解决方案2】:

您可以创建一个覆盖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);
    }
}

【讨论】:

  • CodePaste.net 链接已过期。有机会转发吗?
  • 我真的很想看看你提到的整个示例代码。不幸的是,您的链接已损坏:(您是否有机会提供替代链接,以便我可以查看您的示例代码?
  • 将代码添加到帖子中。希望有帮助!抱歉,链接失效了。
  • 非常感谢您。让我免于重写大量表单!
  • -1 当 url 包含查询字符串时,这不起作用。斜杠将放置在查询字符串之后。
【解决方案3】:

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

我遇到的唯一问题是 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】:

    上面的codingbug解决方案非常好。我需要一些非常相似的东西,但只适用于我的根 URL。我知道这可能存在问题,但这就是我所做的。它似乎在我所有的环境中都可以正常工作。我认为它也有效,因为它只是我们第一次来时的主页,没有培训斜线。这是我试图避免的一种情况。如果这是你想避免的,这对你有用。

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

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

    注意:我指望 Home\Index 会被路由引擎从 URL 中删除。

    【讨论】:

      【解决方案5】:

      我知道有更多赞成的答案,但最佳投票的答案不适用于我的情况。需要我说我找到了一个更简单的解决方案。

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

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

      【讨论】:

      • 不,不会。如果这样做,然后使用 RouteUrl("{name of a route"}, new RouteValueDictionary({parameters})) 生成 url,则尾部斜杠会被截断。
      【解决方案6】:

      有一些非常好的答案,但这里有一些 MVC 控制器代码,说明了我如何以非常简单的方式实现它。

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

      希望这对某人有所帮助。

      【讨论】:

        猜你喜欢
        • 2011-08-21
        • 1970-01-01
        • 2021-09-11
        • 1970-01-01
        • 2013-01-18
        • 2013-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多