Comment puis-je avoir des routes en minuscules dans ASP.NET MVC?

Comment puis-je avoir des routes en minuscules, plus un soulignement si possible, dans ASP.NET MVC? Pour que je puisse /dinners/details/2 appeler DinnersController.Details(2) et, si possible, /dinners/more_details/2 appeler DinnersController.MoreDetails(2) ?

Tout cela en utilisant encore des patterns comme {controller}/{action}/{id} .

Avec System.Web.Routing 4.5, vous pouvez implémenter cela directement en définissant la propriété LowercaseUrls de RouteCollection:

 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 } ); } 

En supposant que vous le faites pour des raisons de référencement, vous souhaitez redirect les URL entrantes en minuscules (comme indiqué dans de nombreux liens de cet article).

 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) { ssortingng 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 ssortingngs lowercaseURL = lowercaseURL.ToLower() + HttpContext.Current.Request.Url.Query; Response.Clear(); Response.Status = "301 Moved Permanently"; Response.AddHeader("Location", lowercaseURL); Response.End(); } } } 

Ces deux tutoriels ont aidé quand je voulais faire la même chose et bien travailler:

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

EDIT: Pour les projets avec des zones, vous devez modifier la méthode 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, ((ssortingng)v.Value).ToLowerInvariant()); break; default: lowerCaseValues.Add(v.Key.ToLowerInvariant(), v.Value); break; } } return base.GetVirtualPath(requestContext, lowerCaseValues); } 

Si vous utilisez UrlHelper pour générer le lien, vous pouvez simplement spécifier le nom de l’action et du contrôleur en minuscule:

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

Résultats dans: / media / photos / delete / 64 (même si mon contrôleur et l’action sont des casques).

Je l’ai trouvé au Coder Journal de Nick Berardi , mais il n’avait pas d’informations sur la façon de mettre en œuvre la classe LowercaseRoute . Par conséquent, republiez ici avec des informations supplémentaires.

Commencez par étendre la classe Route à LowercaseRoute

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

Modifiez ensuite la méthode RegisterRoutes de Global.asax.cs

 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 //); } 

Je voudrais cependant connaître un moyen d’utiliser les routes.MapRoute …

Vous pouvez continuer à utiliser la syntaxe MapRoute en ajoutant cette classe en tant qu’extension de RouteCollection:

 public static class RouteCollectionExtension { public static Route MapRouteLowerCase(this RouteCollection routes, ssortingng name, ssortingng url, object defaults) { return routes.MapRouteLowerCase(name, url, defaults, null); } public static Route MapRouteLowerCase(this RouteCollection routes, ssortingng name, ssortingng 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; } } 

Maintenant, vous pouvez utiliser dans le démarrage de votre application “MapRouteLowerCase” au lieu de “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 ); } 

Si vous avez utilisé ASP.NET Core, vous devriez probablement regarder ceci :

Ajoutez la ligne suivante à la méthode ConfigureServices de la classe Startup .

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

Cela a en fait deux réponses:

  1. Vous pouvez déjà le faire: le moteur de routage effectue une comparaison insensible à la casse. Si vous tapez une route minuscule, celle-ci sera acheminée vers le contrôleur et l’action appropriés.
  2. Si vous utilisez des contrôles qui génèrent des liens de routage (ActionLink, RouteLink, etc.), ils produiront des liens en casse mixte à moins que vous ne remplaciez ce comportement par défaut.

Vous êtes seul pour les soulignés, mais …

Pourriez-vous utiliser l’atsortingbut ActionName?

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

Je ne pense pas que l’affaire soit importante. More_Details, more_DETAILS, mOrE_DeTaIL dans l’URL vous amènent tous à la même action de contrôleur.