ASP.NET MVC에서 소문자 경로를 사용하려면 어떻게해야합니까?


145

ASP.NET MVC에서 소문자와 가능한 경우 밑줄을 사용하여 라우팅 할 수 있습니까? 그래서 내가 가진 것이라고 /dinners/details/2전화를 DinnersController.Details(2), 가능하다면, 그리고 /dinners/more_details/2전화를 DinnersController.MoreDetails(2)?

이 모든 것은 여전히 ​​같은 패턴을 사용합니다 {controller}/{action}/{id}.


어쨌든 여러 가지 이유로 모든 경로를 수동으로 작성했으며 CRUD뿐만 아니라 다른 것으로도 피하는 것이 어렵다고 생각합니다. 방금 소문자로 썼습니다.
pupeno

웹 양식 사용 ? 여기로 이동 : msdn.microsoft.com/en-us/library/...를 . (저는 점차 프로젝트를 웹 양식에서 MVC로 변환하고 있으며 프로젝트에 둘 다 가지고 있습니다)
Jess

확신 기본적으로이 작업을 수행 할 수있는 메신저

소문자 또는 대문자로 경로를 입력하면 중요하지 않다고 생각합니다.

답변:


238

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

4
이것은 4.0에서 가장 간단한 일입니다.
Paul Turner

1
이것이 정상에 있었으면 좋겠다 ... 거의 많은화물이 코드를 작성했습니다!
akatakritos

2
좋은 답변 :-) 후자의 SEO 부분은 HTTP 모듈에 잘 맞습니다.
David Kirkland

1
@Aaron Sherman Application_BeginRequest 부분은 어디로 가야합니까? 내부 공용 클래스 RouteConfig 및 if 외부에있을 때 오류가 발생합니다.
Richard Mišenčík 2016 년

1
@ richard-mišenčík Global.asax 파일에 추가
ITmeze 2016 년

44

이 두 튜토리얼은 똑같은 일을하고 잘 작동하고 싶을 때 도움이되었습니다.

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

9
GONeale 링크가 변경되었습니다. URL은 이제 goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc
Daniel Liuzzi

4
@Derek-아닙니다. 영역을 사용할 때 튜토리얼이 고장납니다. 3 일 동안 모든 것을 시도한 후 ... 더 나은 해결책을 찾았습니다. 속성 라우팅이라는 라이브러리가 있습니다. 문제를 해결하고 인생을 훨씬 쉽게 만듭니다. philliphaydon.com/2011/08/…
Phill

6
mvc 4의 경우 속성 라우트를 사용하는 더 나은 솔루션이 있습니다 .LowercaseUrls = true; dhuvelle.com/2012/11/tips-for-aspnet-mvc-4-lowercase-urls.html에
Marc Cals

4
@GONeale URL은 어떻게 되었습니까? 두 번째 링크는 이제 죽었습니다! 제목은 " 인터넷에서 최고의 사라 에일 사이트"입니다
누가

2
@ chteuchteu 그 링크는 저에게 효과가 없었지만 이것은 효과 가있었습니다.
chue x


21

UrlHelper를 사용하여 링크를 생성하는 경우 조치 및 컨트롤러 이름을 소문자로 간단히 지정할 수 있습니다.

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

결과 : / media / photos / delete / 64 (내 컨트롤러와 액션이 파스칼 케이스 임에도 불구하고).


16
중앙 위치에서이 작업을 수행하는 것이 가장 쉽고 가장 표준적인 솔루션이라고 생각합니다. 이것은 인라인 CSS만큼 나쁩니다. (명백히 15 명은 인라인 CSS를 사용합니다).
머핀 남자

Linux 서버에서도 마찬가지입니까?
QMaster

15

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

그런 다음 RegisterRoutesGlobal.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를 사용하는 방법을 알고 싶습니다.


GONeale의 기사는 쓸 수 있도록 확장 방법을 제공한다 routes.MapRouteLowercase(...: 상기 이외 좋네요있는 goneale.wordpress.com/2008/12/19/...
드류 녹스

1
GONeale의 전체 블로그가 사라졌습니다. 다음은 유사한 내용 (및 동일한 확장 방법)을 가진 다른 블로그 항목 입니다. 중복 컨텐츠를 줄이기 위해 이러한 상황을 해결합니다.
patridge

11

이 클래스를 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
        );
    }

사람이 읽기를 들어, LowercaseRoute이 나타납니다 위의 첫 번째 코드에서 클래스에서 와서 이 다른 대답
chue가 X

6

실제로 두 가지 답변이 있습니다.

  1. 경로 엔진은 대소 문자를 구분하지 않습니다. 소문자 경로를 입력하면 해당 컨트롤러 및 작업으로 경로가 지정됩니다.
  2. 경로 링크 (ActionLink, RouteLink 등)를 생성하는 컨트롤을 사용하는 경우이 기본 동작을 무시하지 않으면 대소 문자가 혼합 된 링크가 생성됩니다.

당신은 밑줄로 당신 자신에 있습니다.


2

ActionName 속성을 사용할 수 있습니까?

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

 }

나는 사건이 중요하다고 생각하지 않습니다. URL의 More_Details, more_DETAILS, mOrE_DeTaIL은 모두 동일한 컨트롤러 작업으로 연결됩니다.


나는 그것을 시도하지 않았다-당신이 어느 쪽을 사용하게 할 것인가? ( "moredetails"또는 "more_details")
GalacticCowboy

후속 조치를 시도했지만 지정된 이름을 사용해야하므로 아니오, 어떤 식 으로든 처리 할 수 ​​없습니다. 또한 제어기 조치 및보기를 구성한 방법에 따라보기 이름을 명시 적으로 지정해야 할 수도 있습니다.
GalacticCowboy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.