visual validar totitlecase studio primera minusculas mayusculas mayuscula letra convertir cadena c# asp.net-mvc asp.net-mvc-4

c# - validar - Conservar mayúsculas y minúsculas en los parámetros de ruta con LowercaseUrls habilitado



totitlecase c# (4)

Estoy usando routes.LowercaseUrls = true; en mi aplicación MVC 4 que funciona muy bien. Sin embargo, los parámetros también se mostrarán en minúscula, así que si tengo una ruta como

routes.MapRoute( name: "MyController", url: "foo/{hash}/{action}", defaults: new { controller = "MyController", action = "Details" } );

El enlace generado con

@Html.ActionLink("my link", "Details", new { hash=ViewBag.MyHash })

también tendrá la {hash} -parte de la URL en minúscula, por ejemplo, si ViewBag.MyHash = "aX3F5U" , el enlace generado será /foo/ax3f5u lugar de /foo/aX3F5U

¿Hay alguna manera de forzar a MVC a que solo ponga en minúscula el controlador y las partes de acción?

Para las versiones anteriores de MVC, el camino a seguir parecía ser implementar una subclase personalizada de Route , sin embargo, no sé cómo / dónde crear una instancia, ya que la firma de los constructores de ruta es bastante diferente de MapRoute y estoy esperando que haya una manera más simple.


Aquí hay una manera simple de hacer esto,

public class MyRoute : Route { public MyRoute(string url, object defaults): base(url, new RouteValueDictionary(defaults), new MvcRouteHandler()) { } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { if (values["action"] != null) values["action"] = values["action"].ToString().ToLowerInvariant(); if (values["controller"] != null) values["controller"] = values["controller"].ToString().ToLowerInvariant(); return base.GetVirtualPath(requestContext, values); } } routes.Add("Default",new MyRoute("{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = MyUrlParameter.Optional }));

Vea esta publicación en el blog para más detalles.


Creo que la solución con una subclase personalizada de Route será lo suficientemente buena y simple, pero al mismo tiempo un poco fea :)

Puede agregar un CustomRoute en el método RegisterRoute de RouteConfig.cs . Agregue el siguiente código en lugar de routes.MapRoute

var route = new CustomRoute(new Route( url: "{controller}/{action}/{id}", defaults: new RouteValueDictionary() { { "controller", "Home" }, { "action", "Index" }, { "id", UrlParameter.Optional } }, routeHandler: new MvcRouteHandler() )); routes.Add(route);

La implementación de CustomRoute particular puede verse así:

public class CustomRoute : RouteBase { private readonly RouteBase route; public CustomRoute(RouteBase route) { this.route = route; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { values = new RouteValueDictionary(values.Select(v => { return v.Key.Equals("action") || v.Key.Equals("controller") ? new KeyValuePair<String, Object>(v.Key, (v.Value as String).ToLower()) : v; }).ToDictionary(v => v.Key, v => v.Value)); return route.GetVirtualPath(requestContext, values); } public override RouteData GetRouteData(HttpContextBase httpContext) { return route.GetRouteData(httpContext); } }

Sin embargo, no es una implementación óptima. Un ejemplo completo podría usar una combinación de extensiones en RouteCollection y un Route child personalizado para mantenerlo lo más cerca posible de la sintaxis de routes.MapRoute(...) :

Clase LowRoseRoute:

public class LowercaseRoute : Route { public LowercaseRoute(string url, IRouteHandler routeHandler) : base(url, routeHandler) { } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { values = new RouteValueDictionary(values.Select(v => { return v.Key.Equals("action") || v.Key.Equals("controller") ? new KeyValuePair<String, Object>(v.Key, (v.Value as String).ToLower()) : v; }).ToDictionary(v => v.Key, v => v.Value)); return base.GetVirtualPath(requestContext, values); } }

Clase RouteCollectionExtensions:

public static class RouteCollectionExtensions { [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")] public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url) { return MapLowercaseRoute(routes, name, url, null /* defaults */, (object)null /* constraints */); } [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")] public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults) { return MapLowercaseRoute(routes, name, url, defaults, (object)null /* constraints */); } [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")] public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults, object constraints) { return MapLowercaseRoute(routes, name, url, defaults, constraints, null /* namespaces */); } [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")] public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url, string[] namespaces) { return MapLowercaseRoute(routes, name, url, null /* defaults */, null /* constraints */, namespaces); } [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")] public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces) { return MapLowercaseRoute(routes, name, url, defaults, null /* constraints */, namespaces); } [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")] public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) { if (routes == null) { throw new ArgumentNullException("routes"); } if (url == null) { throw new ArgumentNullException("url"); } Route route = new LowercaseRoute(url, new MvcRouteHandler()) { Defaults = CreateRouteValueDictionary(defaults), Constraints = CreateRouteValueDictionary(constraints), DataTokens = new RouteValueDictionary() }; if ((namespaces != null) && (namespaces.Length > 0)) { route.DataTokens["Namespaces"] = namespaces; } routes.Add(name, route); return route; } private static RouteValueDictionary CreateRouteValueDictionary(object values) { var dictionary = values as IDictionary<string, object>; if (dictionary != null) { return new RouteValueDictionary(dictionary); } return new RouteValueDictionary(values); } }

Ahora puede usar MapLowercaseRoute lugar de MapRoute , por lo que

routes.MapRoute( name: "MyController", url: "foo/{hash}/{action}", defaults: new { controller = "MyController", action = "Details" } );

simplemente se convierte

routes.MapLowercaseRoute( name: "MyController", url: "foo/{hash}/{action}", defaults: new { controller = "MyController", action = "Details" } );

exponiendo el comportamiento deseado.


Es simple como 1.2.3,

mira este ejemplo

routes.MapRouteLowercase( // changed from routes.MapRoute "Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional } );

Es sencillo descargarlo e instalarlo a través de Nuget, lo uso. PM> Install-Package LowercaseRoutesMVC

http://lowercaseroutesmvc.codeplex.com/


Si RouteCollection.NormalizeVirtualPath método privado RouteCollection.NormalizeVirtualPath , verá que simplemente utiliza virtualPath.ToLowerInvariant() . Entonces no hay forma de manejar eso. Incluso si creas tu propia ruta, será en minúscula.

Pero lo que puedes hacer es agregar hash después del signo ''#'', es decir, "foo/{action}/#{hash}" . No lo he intentado, pero debería funcionar. Solo mira la implementación de NormalizeVirtualPath .