ASP.NET MVC路由上的尾部斜杠
在最新的MVC预览中,我将此路由用于旧版URL:
routes.MapRoute( "Legacy-Firefox", // Route name "Firefox-Extension/", // URL with parameters new { controller = "Home", action = "Firefox", id = "" } // Parameter defaults );
问题在于这两个URL都可以工作:
http://example.com/Firefox-Extension
http://example.com/Firefox-Extension/
我只希望第二个工作(用于SEO)。另外,当我创建到该页面的链接时,路由引擎会给我返回一个没有尾随斜杠的URL。
这是我用来生成链接的代码:
<%= Html.ActionLink("Firefox Extension", "Firefox", "Home")%>
我相信可以通过使用HTTP处理程序执行301重定向到带有斜杠的URL来解决第一个问题。但是,我想用斜杠链接到URL,我希望不必用斜杠对版本进行硬编码。
有人知道如何强制路由使用斜杠吗?
解决方案
编写链接时,应始终包含最后的斜杠。我不知道这是否适用于mvc框架(或者一般来说是URL路由),但是我知道对于静态资源,如果不加斜杠,则会增加两次请求的开销。
斜杠立即将URL标识为指向目录。无需解析文件。
同样,当我们使用URL路由时,我认为这并不适用,但是我没有对此进行研究。
在此处查看有关尾随斜杠的文章
编辑:
考虑到这一点...我认为最好不要使用斜杠,而应该尝试将其包括在内。当我们使用url路由时,我们是在使用URL直接路由到资源。与指向带有index.html或者default.aspx的目录相反,我们指向的是特定文件。
我知道差异是细微的,但最好还是对Routed Urls采取不加斜线的态度,而不是与框架抗争。
实际指向目录时,请严格使用尾部斜杠。以为我猜想,如果我们真的不喜欢,可以每次都在末尾添加一个斜杠。
如果通过RouteLink进行包装,则可以轻松解决该问题。
例如,我有一个包装方法RouteLinkEx:
public static string RouteLinkEx(this HtmlHelper helper,string text,string routeName,RouteValueDictionary rvd,object htmlAttributes) { UrlHelper uh = new UrlHelper(helper.ViewContext.RequestContext,helper.RouteCollection); // Add trailing slash to the url of the link string url = uh.RouteUrl(routeName,rvd) + "/"; TagBuilder builder = new TagBuilder("a") { InnerHtml = !string.IsNullOrEmpty(text) ? HttpUtility.HtmlEncode(text) : string.Empty }; builder.MergeAttributes(new RouteValueDictionary(htmlAttributes)); builder.MergeAttribute("href",url); return builder.ToString(TagRenderMode.Normal); //--- }
如我们所见,我首先使用参数来生成URL。然后我在URL的末尾添加了" /"。然后我使用这些URL生成了完整的链接。
这是RouteLinkEx(HtmlHelper,string,string,object)的重载
public static string RouteLinkEx(this HtmlHelper helper, string text, string routeName, object routeValues) { UrlHelper uh = new UrlHelper(helper.ViewContext.RequestContext); // Add trailing slash to the url of the link string url = uh.RouteUrl(routeName, routeValues) + "/"; TagBuilder builder = new TagBuilder("a") { InnerHtml = !string.IsNullOrEmpty(text) ? HttpUtility.HtmlEncode(text) : string.Empty }; //builder.MergeAttributes(new RouteValueDictionary(htmlAttributes)); builder.MergeAttribute("href", url); return builder.ToString(TagRenderMode.Normal); //--- }
我偶然发现了这篇博客文章:
http://www.ytechie.com/2008/10/aspnet-mvc-what-about-seo.html
今天早上在StackOverflow上遇到这个问题之前。该博客文章(来自该问题的作者)对Scott Hanselman的这篇博客文章进行了追溯,并给出了以下问题的答案:
http://www.hanselman.com/blog/ASPNETMVCAndTheNewIIS7RewriteModule.aspx
我很惊讶地发现这里还没有链接,所以我添加了它。 :)
Scott的答案建议使用URL重写。
这是我的ASP.NET MVC 2版本
public static MvcHtmlString RouteLinkEx(this HtmlHelper helper, string text, RouteValueDictionary routeValues) { return RouteLinkEx(helper, text, null, routeValues, null); } public static MvcHtmlString RouteLinkEx(this HtmlHelper htmlHelper, string text, string routeName, RouteValueDictionary routeValues, object htmlAttributes) { string url = UrlHelper.GenerateUrl(routeName, null, null, null, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, false); var builder = new TagBuilder("a") { InnerHtml = !string.IsNullOrEmpty(text) ? HttpUtility.HtmlEncode(text) : string.Empty }; builder.MergeAttributes(new RouteValueDictionary(htmlAttributes)); // Add trailing slash to the url of the link builder.MergeAttribute("href", url + "/"); return MvcHtmlString.Create(builder.ToString(TagRenderMode.Normal)); }