我如何在ASP.NET MVC中使用小写路由?

如何在ASP.NET MVC中使用小写字母和下划线(如果可能的话)? 所以,我会有/dinners/details/2 DinnersController.Details(2) /dinners/details/2调用DinnersController.Details(2) ,如果可能的话, /dinners/more_details/2调用DinnersController.MoreDetails(2)

所有这些同时仍然使用{controller}/{action}/{id}

使用System.Web.Routing 4.5,您可以通过设置RouteCollection的LowercaseUrls属性来实现这一点:

 public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.LowercaseUrls = true; routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } 

此外,假设你正在做这个SEO的原因,你想redirect传入的url小写(如本文中的许多链接所述)。

 protected void Application_BeginRequest(object sender, EventArgs e) { //You don't want to redirect on posts, or images/css/js bool isGet = HttpContext.Current.Request.RequestType.ToLowerInvariant().Contains("get"); if (isGet && HttpContext.Current.Request.Url.AbsolutePath.Contains(".") == false) { string lowercaseURL = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath); if (Regex.IsMatch(lowercaseURL, @"[AZ]")) { //You don't want to change casing on query strings lowercaseURL = lowercaseURL.ToLower() + HttpContext.Current.Request.Url.Query; Response.Clear(); Response.Status = "301 Moved Permanently"; Response.AddHeader("Location", lowercaseURL); Response.End(); } } } 

当我想要做同样的事情并且运作良好的时候,这两篇教程很有帮助:

http://www.coderjournal.com/2008/03/force-mvc-route-url-lowercase/ http://goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc/

编辑:对于具有区域的项目,您需要修改GetVirtualPath()方法:

 public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { var lowerCaseValues = new RouteValueDictionary(); foreach (var v in values) { switch (v.Key.ToUpperInvariant()) { case "ACTION": case "AREA": case "CONTROLLER": lowerCaseValues.Add(v.Key, ((string)v.Value).ToLowerInvariant()); break; default: lowerCaseValues.Add(v.Key.ToLowerInvariant(), v.Value); break; } } return base.GetVirtualPath(requestContext, lowerCaseValues); } 

如果您使用UrlHelper生成链接,则可以简单地将操作和控制器的名称指定为小写:

 itemDelete.NavigateUrl = Url.Action("delete", "photos", new { key = item.Key }); 

结果在:/ media / photos / delete / 64(即使我的控制器和操作是pascal的情况下)。

我在Nick Berardi的Coder Journal发现了这个,但是它没有关于如何实现LowercaseRoute类的信息。 因此在这里重新发布更多的信息。

首先将Route类扩展为LowercaseRoute

 public class LowercaseRoute : Route { public LowercaseRoute(string url, IRouteHandler routeHandler) : base(url, routeHandler) { } public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler) : base(url, defaults, routeHandler) { } public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler) : base(url, defaults, constraints, routeHandler) { } public LowercaseRoute(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.ToLowerInvariant(); return path; } } 

然后修改Global.asax.cs的RegisterRoutes方法

 public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.Add(new LowercaseRoute("{controller}/{action}/{id}", new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }), new MvcRouteHandler())); //routes.MapRoute( // "Default", // Route name // "{controller}/{action}/{id}", // URL with parameters // new { controller = "Home", action = "Index", id = "" } // Parameter defaults //); } 

然而,我想知道一种方法来使用routes.MapRoute …

您可以继续使用MapRoute语法,将此类作为RouteCollection的扩展添加:

 public static class RouteCollectionExtension { public static Route MapRouteLowerCase(this RouteCollection routes, string name, string url, object defaults) { return routes.MapRouteLowerCase(name, url, defaults, null); } public static Route MapRouteLowerCase(this RouteCollection routes, string name, string url, object defaults, object constraints) { Route route = new LowercaseRoute(url, new MvcRouteHandler()) { Defaults = new RouteValueDictionary(defaults), Constraints = new RouteValueDictionary(constraints) }; routes.Add(name, route); return route; } } 

现在,您可以在应用程序的启动“MapRouteLowerCase”而不是“MapRoute”中使用:

  public void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // Url shortcuts routes.MapRouteLowerCase("Home", "", new { controller = "Home", action = "Index" }); routes.MapRouteLowerCase("Login", "login", new { controller = "Account", action = "Login" }); routes.MapRouteLowerCase("Logout", "logout", new { controller = "Account", action = "Logout" }); routes.MapRouteLowerCase( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = "" } // Parameter defaults ); } 

如果你碰巧使用ASP.NET Core,你可能应该看看这个 :

将以下行添加到Startup类的ConfigureServices方法。

 services.AddRouting(options => options.LowercaseUrls = true); 

这实际上有两个答案:

  1. 你可以做到这一点:路由引擎不区分大小写的比较。 如果您键入小写路由,它将被路由到适当的控制器和操作。
  2. 如果您正在使用生成路由链接的控件(ActionLink,RouteLink等),它们将生成混合大小写的链接,除非您重写此默认行为。

虽然你自己为下划线

你可以使用ActionName属性吗?

  [ActionName("more_details")] public ActionResult MoreDetails(int? page) { } 

我不认为案件很重要。 More_Details,more_DETAILS,URL中的mOrE_DeTaILs都会带你到同一个Controller Action。