asp.net-mvc 在每个 url 的末尾添加斜杠?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1385265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:50:05  来源:igfitidea点击:

Add a trailing slash at the end of each url?

asp.net-mvcurl-routing

提问by Galilyou

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 更改为 /register,没有尾部斜杠。我修改了我的路由系统,如下所示:

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

Still the required trailing slash doesn't get added automatically!
I looked up this questionand this questionbut 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 路由系统。
那你们说呢?

回答by Schmidty

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

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

回答by aolde

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

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

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().

现在您所要做的就是使用routes.MapRouteTrailingSlash()而不是注册路由routes.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);
    }
}

回答by Akaoni

Nice clean solution, 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;       
}

回答by Bobby Ortiz

The above solution by codingbug is very nice. I needed something very similar, 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 than 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\Index。

回答by radu florescu

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.

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

回答by theGiantOtter

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

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

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

Hope this helps someone.

希望这可以帮助某人。