我这里有点问题。我需要在我正在处理的网站的每个网址末尾添加一个尾部斜杠。我将网站内的所有链接定义为具有如下的尾部斜杠:
<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路由系统。
那么你们怎么说呢?
答案 0 :(得分:47)
RouteCollection类现在有一个AppendTrailingSlash布尔值,您可以为此行为设置为true。
答案 1 :(得分:20)
您可以创建一个覆盖GetVirtualPath
方法的新Route。在此方法中,您将向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);
}
}
答案 2 :(得分:5)
漂亮干净的解决方案,codingbug !!
我遇到的唯一问题是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;
}
答案 3 :(得分:3)
通过codingbug的上述解决方案非常好。我需要一些非常相似的东西,但仅限于我的根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。
答案 4 :(得分:1)
我知道有更多的赞成答案,但最好的投票答案对我的案子不起作用。需要我说我找到了一个更容易的解决方案。
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}/", <-- trailing slash here
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
这将作为尾随斜线&#34; /&#34;在所有情况下。
答案 5 :(得分:1)
有一些非常好的答案,但这里有一些MVC Controller代码,我是如何在一个非常简单的get中实现它的。
public ActionResult Orders()
{
if (!Request.Path.EndsWith("/"))
{
return RedirectPermanent(Request.Url.ToString() + "/");
}
return View();
}
希望这有助于某人。