Add a trailing slash at the end of each url?
Solution 1:
The RouteCollection Class now has a AppendTrailingSlash boolean which you can set to true for this behavior.
Solution 2:
You can create a new Route which overrides the GetVirtualPath
method. In this method you add a trailing slash to the VirtualPath
. Like this:
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
Now all you have to do is register the routes with routes.MapRouteTrailingSlash()
instead of 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.
Update: Because the CodePaste link is down, here is the full code:
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);
}
}
Solution 3:
Nice clean solution, codingbug!!
Only problem I ran into was double trailing slashes for the home page in MVC3.
Razor example:
@Html.ActionLink("Home", "Index", "Home")
Linked to:
http://mysite.com//
To fix this I tweaked the GetVirtualPath override:
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;
}
Solution 4:
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.
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.
Note: I am counting on Home\Index to be removed from the URL by the routing engine.