asp.net-mvc - validaciones - vista parciales
¿Cómo puedo tener rutas en minúsculas en ASP.NET MVC? (8)
¿Cómo puedo tener rutas en minúsculas, además de subrayado si es posible, en ASP.NET MVC? Para que yo tenga /dinners/details/2
llame a DinnersController.Details(2)
y, si es posible, /dinners/more_details/2
llame a DinnersController.MoreDetails(2)
?
Todo esto sin dejar de usar patrones como {controller}/{action}/{id}
.
¿Podría usar el atributo ActionName?
[ActionName("more_details")]
public ActionResult MoreDetails(int? page)
{
}
No creo que el caso importe. More_Details, more_DETAILS, mOrE_DeTaILs en la URL lo llevan a la misma Acción del controlador.
Con System.Web.Routing 4.5 puede implementar esto de manera directa estableciendo la propiedad 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 }
);
}
También asumiendo que estás haciendo esto por razones de SEO, quieres redirigir las URL entrantes a minúsculas (como se dice en muchos de los enlaces de este artículo).
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, @"[A-Z]"))
{
//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();
}
}
}
Encontré esto en http://www.coderjournal.com/2008/03/force-mvc-route-url-lowercase/ , pero no tenía información sobre cómo implementar la clase LowercaseRoute
. Por lo tanto, volver a publicar aquí con información adicional.
Primero amplíe la clase Route
a Route
en 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;
}
}
A continuación, modifique el método 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
//);
}
Sin embargo, me gustaría saber una forma de usar routes.MapRoute ...
Esto en realidad tiene dos respuestas:
- Ya puede hacer esto: el motor de ruta hace una comparación insensible a mayúsculas y minúsculas. Si escribe una ruta en minúscula, se enrutará al controlador y a la acción apropiados.
- Si está utilizando controles que generan enlaces de ruta (ActionLink, RouteLink, etc.) producirán enlaces de casos mezclados a menos que anule este comportamiento predeterminado.
Sin embargo, estás solo por los guiones bajos ...
Estos dos tutoriales me ayudaron cuando quería hacer lo mismo y trabajar bien:
http://www.coderjournal.com/2008/03/force-mvc-route-url-lowercase/ http://goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc/
EDITAR: para proyectos con áreas, debe modificar el método 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);
}
Puede continuar usando la sintaxis de MapRoute agregando esta clase como una extensión a 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;
}
}
Ahora puede usar en el inicio de su aplicación "MapRouteLowerCase" en lugar 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 está utilizando UrlHelper para generar el enlace, puede simplemente especificar el nombre de la acción y el controlador como minúsculas:
itemDelete.NavigateUrl = Url.Action("delete", "photos", new { key = item.Key });
Resultados en: / media / photos / delete / 64 (aunque mi controlador y acción son pascal).
Si usó ASP.NET Core, probablemente debería echar un vistazo a this :
Agregue la siguiente línea al método
ConfigureServices
de la clase deStartup
.
services.AddRouting(options => options.LowercaseUrls = true);