ASP.NET MVC에서 소문자와 가능한 경우 밑줄을 사용하여 라우팅 할 수 있습니까? 그래서 내가 가진 것이라고 /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 이유로 인해이 작업을 수행한다고 가정하면 들어오는 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, @"[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();
}
}
}
답변
이 두 튜토리얼은 똑같은 일을하고 잘 작동하고 싶을 때 도움이되었습니다.
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);
}
답변
ASP.NET Core를 사용한 경우 다음을 살펴보아야 합니다 .
클래스 의
ConfigureServices
메소드에 다음 행을 추가하십시오Startup
.services.AddRouting(options => options.LowercaseUrls = true);
답변
UrlHelper를 사용하여 링크를 생성하는 경우 조치 및 컨트롤러 이름을 소문자로 간단히 지정할 수 있습니다.
itemDelete.NavigateUrl = Url.Action("delete", "photos", new { key = item.Key });
결과 : / media / photos / delete / 64 (내 컨트롤러와 액션이 파스칼 케이스 임에도 불구하고).
답변
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;
}
}
그런 다음 RegisterRoutes
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
//);
}
그러나 route.MapRoute를 사용하는 방법을 알고 싶습니다.
답변
이 클래스를 RouteCollection의 확장으로 추가하여 MapRoute 구문을 계속 사용할 수 있습니다.
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;
}
}
이제 “MapRoute”대신 응용 프로그램 시작 “MapRouteLowerCase”에서 사용할 수 있습니다.
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
);
}
답변
실제로 두 가지 답변이 있습니다.
- 경로 엔진은 대소 문자를 구분하지 않습니다. 소문자 경로를 입력하면 해당 컨트롤러 및 작업으로 경로가 지정됩니다.
- 경로 링크 (ActionLink, RouteLink 등)를 생성하는 컨트롤을 사용하는 경우이 기본 동작을 무시하지 않으면 대소 문자가 혼합 된 링크가 생성됩니다.
당신은 밑줄로 당신 자신에 있습니다.