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

时间:2021-08-06 10:45:43

I have a little problem here. I need to add a trailing slash at the end of each url in the site I'm working on. I defined all the links inside the site to have a trailing slash like so:

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

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

While this works fine there's still one tiny issue: it's with the generated urls that come from calling RedirectToAction(). For example:

虽然这很好,但仍然有一个小问题:它与来自调用RedirectToAction()的生成的url有关。例如:

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

Will cause the url to change to /register with no trailing slash. I modified my routing system as so:

将导致url更改为/寄存器,没有斜杠。我修改了我的路由系统如下:

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

Still the required trailing slash doesn't get added automatically!
I looked up this question and this question but these are totally different as I'm not using any url rewriting libraries, i'm just using asp.net mvc routing system.
So what do you say guys?

仍然需要的尾部斜杠不会自动添加!我查了这个问题和这个问题,但它们是完全不同的,因为我没有使用任何url重写库,我只是使用asp.net mvc路由系统。你们说什么?

6 个解决方案

#1


46  

The RouteCollection Class now has a AppendTrailingSlash boolean which you can set to true for this behavior.

RouteCollection类现在有一个AppendTrailingSlash boolean,您可以将其设置为true以满足这种行为。

#2


21  

You can create a new Route which overrides the GetVirtualPath method. In this method you add a trailing slash to the VirtualPath. Like this:

您可以创建一个新的路由来覆盖GetVirtualPath方法。在此方法中,向虚拟路径添加尾斜线。是这样的:

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
     VirtualPathData path = base.GetVirtualPath(requestContext, values);

     if (path != null)
         path.VirtualPath = path.VirtualPath + "/";
     return path;
}

For brevity I posted the whole example on CodePaste.net

为了简单起见,我在CodePaste.net上发布了整个示例

Now all you have to do is register the routes with routes.MapRouteTrailingSlash() instead of routes.MapRoute().

现在您所要做的就是使用routing . maproutetrailingslash()而不是route . maproute()注册路由。

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

The route will then add a slash to the path when the GetVirtualPath() is called. Which RedirectToAction() will do.

然后,当调用GetVirtualPath()时,路由将向路径添加一个斜线。RedirectToAction()就可以了。

Update: Because the CodePaste link is down, here is the full code:

更新:因为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  

Nice clean solution, codingbug!!

干净的解决方案,codingbug ! !

Only problem I ran into was double trailing slashes for the home page in MVC3.

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

Razor example:

剃须刀的例子:

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

Linked to:
http://mysite.com//

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

To fix this I tweaked the GetVirtualPath override:

为了解决这个问题,我修改了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  

The above solution by codingbug is very nice. I needed something very simular, but only for my root URL. I know there are possible problems with this, but here is what I did. It seems to work just fine in all of my environments. I think it works too, because it is only our Home page when they first come and do not have the training slash. That is the one case I was trying to avoid. If that is what you want to avoid, this will work for you.

codingbug提供的上述解决方案非常好。我需要一些非常简单的东西,但只针对我的根URL。我知道这可能会有问题,但这就是我所做的。在我的所有环境中,它似乎都能正常工作。我认为它也可以,因为这只是我们的主页,当他们第一次来的时候,没有培训的削减。这是我试图避免的一个情况。如果这是你想要避免的,这将对你有效。

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

If it turns out I need more tan this. I will probably use code that codingbug provided. Until then, I like to keep it simple.

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

Note: I am counting on Home\Index to be removed from the URL by the routing engine.

注意:我希望通过路由引擎从URL中删除Home\索引。

#5


1  

I know there are more upvoted answers, but the best voted answer didn't work for my case. Need I say that I found a far easier solution.

我知道有更多向上的答案,但最好的投票答案并不适合我的情况。需要我说我找到了一个简单得多的解决办法。

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

This will act as trailing slash "/" in all the cases.

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

#6


1  

There are some really good answers but here is some MVC Controller code of how I implement it in a very simple get.

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

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

Hope this helps someone.

希望这可以帮助别人。

#1


46  

The RouteCollection Class now has a AppendTrailingSlash boolean which you can set to true for this behavior.

RouteCollection类现在有一个AppendTrailingSlash boolean,您可以将其设置为true以满足这种行为。

#2


21  

You can create a new Route which overrides the GetVirtualPath method. In this method you add a trailing slash to the VirtualPath. Like this:

您可以创建一个新的路由来覆盖GetVirtualPath方法。在此方法中,向虚拟路径添加尾斜线。是这样的:

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
     VirtualPathData path = base.GetVirtualPath(requestContext, values);

     if (path != null)
         path.VirtualPath = path.VirtualPath + "/";
     return path;
}

For brevity I posted the whole example on CodePaste.net

为了简单起见,我在CodePaste.net上发布了整个示例

Now all you have to do is register the routes with routes.MapRouteTrailingSlash() instead of routes.MapRoute().

现在您所要做的就是使用routing . maproutetrailingslash()而不是route . maproute()注册路由。

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

The route will then add a slash to the path when the GetVirtualPath() is called. Which RedirectToAction() will do.

然后,当调用GetVirtualPath()时,路由将向路径添加一个斜线。RedirectToAction()就可以了。

Update: Because the CodePaste link is down, here is the full code:

更新:因为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  

Nice clean solution, codingbug!!

干净的解决方案,codingbug ! !

Only problem I ran into was double trailing slashes for the home page in MVC3.

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

Razor example:

剃须刀的例子:

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

Linked to:
http://mysite.com//

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

To fix this I tweaked the GetVirtualPath override:

为了解决这个问题,我修改了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  

The above solution by codingbug is very nice. I needed something very simular, but only for my root URL. I know there are possible problems with this, but here is what I did. It seems to work just fine in all of my environments. I think it works too, because it is only our Home page when they first come and do not have the training slash. That is the one case I was trying to avoid. If that is what you want to avoid, this will work for you.

codingbug提供的上述解决方案非常好。我需要一些非常简单的东西,但只针对我的根URL。我知道这可能会有问题,但这就是我所做的。在我的所有环境中,它似乎都能正常工作。我认为它也可以,因为这只是我们的主页,当他们第一次来的时候,没有培训的削减。这是我试图避免的一个情况。如果这是你想要避免的,这将对你有效。

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

If it turns out I need more tan this. I will probably use code that codingbug provided. Until then, I like to keep it simple.

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

Note: I am counting on Home\Index to be removed from the URL by the routing engine.

注意:我希望通过路由引擎从URL中删除Home\索引。

#5


1  

I know there are more upvoted answers, but the best voted answer didn't work for my case. Need I say that I found a far easier solution.

我知道有更多向上的答案,但最好的投票答案并不适合我的情况。需要我说我找到了一个简单得多的解决办法。

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

This will act as trailing slash "/" in all the cases.

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

#6


1  

There are some really good answers but here is some MVC Controller code of how I implement it in a very simple get.

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

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

Hope this helps someone.

希望这可以帮助别人。