2010-05-22 8 views
6

this question과 비슷한 점을 좀 더 향상시키고 싶습니다.ASP.NET 라우팅을 사용하여 트리 구조 URL을 라우팅하는 방법은 무엇입니까?

ASP.NET MVC 웹 응용 프로그램이 있습니다.

나는 엔티티 트리를 가지고 있습니다.
예를 들어, IList<Page> 인 Children이라는 속성이있는 Page 클래스입니다. (Page 클래스의 인스턴스는 데이터베이스의 한 행에 해당합니다.)

사이트 소유자는 언제든지 새 페이지를 추가하거나 기존 페이지를 삭제할 수 있으며 URL에는 이러한 변경 사항도 반영되어야합니다.

데이터베이스의 모든 Page에 고유 한 URL을 할당하고 싶습니다.
나는 PageController이라는 컨트롤러로 Page 개체를 처리합니다.

예 URL은 :

http://mysite.com/Page1/ 
http://mysite.com/Page1/SubPage/ 
http://mysite.com/Page/ChildPage/GrandChildPage/ 

당신은 그림을 얻는다.
그래서 모든 단일 Page 개체에 부모 URL과 자체 이름을 더한 자체 URL을 갖게하고 싶습니다.
그 외에도 단일 Page/ (루트) URL로 매핑하는 기능을 원합니다.

나는이 규칙을 적용 할 것 : URL이 다른 경로로 처리하거나, 파일이 지정된 URL에있는 파일 시스템에 존재 할 수있는 경우

  1. , 기본 URL 매핑이
  2. 을 일어나게을
  3. URL이 가상 경로 공급자에 의해 처리 될 수있는 경우, PageController 클래스
에 다른 URL을 매핑, 다른이없는 경우 그
  • 그것을 처리하도록

    나는 또한 this questionalso this onethis one을 찾았지만 첫 두 점에 대한 설명을 제공하지 않았기 때문에별로 도움이되지 않았습니다.

    나는 다음과 같은 가능한 soutions를 참조하십시오

    • 이 invidually 각 페이지에 대한 경로를지도.
      응용 프로그램이 시작될 때 전체 트리로 이동하고 경로 테이블의 끝에 정확히 일치하는 경로를 추가해야합니다.
    • {*path}으로 경로를 추가하고이를 처리하는 사용자 정의 IRouteHandler을 작성할 수 있지만이 핸들러가 모든 것을 처리 할 수 ​​있기 때문에 처음 두 규칙을 어떻게 처리 할 수 ​​있는지 알 수 없습니다.

    지금까지 가장 간단한 해결책이기 때문에 첫 번째 해결 방법이 가장 간단합니다. 하지만 그 경우에도 요청을 처리하기 위해 내가 어떻게 PageController을 만들 수 있는지 확실하지 않습니다.

    정말 고맙게 생각합니다.

    미리 감사드립니다.

    편집 : 이제 모든 답변의 모든 측면을 검토 할 시간이있었습니다. 나는 Neal의 대답을 받아 들였습니다. 그가 일하는 방식에 대해 가장 잘 설명해주는 사람이기 때문입니다. 나는 또한 좋은 아이디어를 제공하기 때문에 다른 모든 대답을 upvoted.

  • 답변

    3

    경로는 컬렉션에 추가 된 순서대로 처리됩니다. 기존 경로 뒤에 맞춤 경로를 추가하여 요청을 처리 할 수있는 마지막 경로인지 확인하십시오. 이렇게하면 기존 파일 (가상 또는 기타)의 경로를 추가 할 수 있으므로 기준 1과 2를 충족 할 수 있습니다.

    기본적으로 MVC 라우팅은 경로 수집에 저장된 경로를 적용하기 전에 기존 파일로 경로를 지정합니다. http://msdn.microsoft.com/en-us/library/system.web.routing.routecollection.routeexistingfiles.aspx을 참조하십시오. (Paul에게 hattip - 코멘트를 보라).

    요청을 페이지 컨트롤러로 라우팅하려면 가상 경로를 검사하는 사용자 지정 경로를 만들고 해당 경로가 데이터베이스의 페이지 패턴과 일치하면 RouteData을 반환합니다. RouteData에 가상 경로에서 적절한 값을 추출하고 (예 : 경로 키를/Parent/Child/Grandchild로 설정) 컨트롤러 키를 페이지 컨트롤러 이름 (예 : Page)으로 설정하고 작업을 작업 이름으로 설정합니다 실행하려는 (예 : 표시). RouteDataMvcRouteHandler (올바른 클래스 이름인지 확실하지 않음)으로 만들어야합니다.

    RouteBaseGetVirtualPath(RequestContext, RouteValueDictionary) 메소드를 오버라이드 (override), 데이터베이스 구동 페이지에 URL을 올바르게 반환됩니다 확인하고 이것은 데이터베이스 기반 페이지에 있는지 확인하기 위해 전달 된 경로 값을 사용하려면이 (필요한 가상 경로 데이터를 생성하는 경우 그렇지 않은 경우는 null를 돌려줍니다).

    최우선 GetRouteDataGetVirtualPath에 대한 도움말

    , System.Web.Routing.RouteBaseSystem.Web.Routing.Route의 반사 된 소스 코드를 보면; 그 후에 Google은 당신의 친구입니다.

    경로는 역순으로 컨트롤러, 동작 및 다른 경로 값이 지정된 URL을 결정하는 데 사용됩니다. 요청한 컨텍스트 내에서이 URL을 사용하여 페이지의 URL을 빌드 할 수 있어야합니다.

    +0

    기존 파일에 대한 경로를 추가하는 이유와 방법은 무엇입니까? 또한, 어떻게 나무의 경로를 만들고 적절한 컨트롤러로 안내 할 수 있습니까? – Venemo

    +1

    필요하지 않습니다. 기본적으로 라우팅 시스템은 기존 파일을 확인하고 일치하는 컨트롤러 및 작업을 찾으려고 할 때이를 지원합니다. – Paul

    +0

    @Paul - 감사합니다. 가상 경로 공급자가 제공하는 파일에도이 기능이 적용됩니까? – Venemo

    1

    하나의 다른 아이디어는 T4 (텍스트 템플릿 변환 도구 키트)를 사용하여 자녀를 한 번 읽고 Global.asax 파일의 콘텐츠를 생성하는 것입니다.

    편집 : Bascially T4로 텍스트 파일 생성을 자동화 할 수 있습니다. 예를 들어 거대한 컬렉션의 항목을 수동으로 복사하고 텍스트 파일 (예 : INSERT INTO [MyTable] (Text) VALUES (@ItemText))에 붙여 넣는 대신 T4 엔진에서 컬렉션을 읽고 이러한 삽입 문을 생성 할 수 있습니다. 그것은 정적이며 런타임을위한 것이 아닙니다.

    매우 유용한 소개는 Pro Entity Framework 4.0에서 찾을 수 있습니다.

    하지만 동적으로 처리해야한다고 말하면이 도구가 도움이되지 않을 수 있습니다.

    +0

    더 자세히 설명해 주시면 기쁘 겠지만, T4에 대해서는 들어 보지 못했습니다. 참고 : 런타임 중에 페이지가 변경 될 수 있습니다. 사이트의 관리자는 원하는만큼 추가/제거/변경할 수 있습니다. – Venemo

    +0

    나를위한 도구가 아님을 지적 해 주셔서 감사합니다. 실제로 컬렉션은 런타임에 변경됩니다. 어쨌든, 시간을내어 대답 해 주셔서 감사합니다. :) – Venemo

    1

    페이지를 저장할 때 페이지 구조를 알 수 있습니다. 따라서 각 페이지에 대한 URL을 생성하여 데이터베이스 레코드에 저장할 수 있습니다. 그런 다음 {*path} 규칙을 사용하고 데이터베이스에서 정확히 일치하는 것을 찾을 수 있습니다. 이 규칙은 규칙 정의의 마지막에 있어야하므로 다른 경로와 일치시킬 수 있습니다.

    예를 들어 Page1에는 상위 페이지가 없습니다. URL은 Page1입니다. SubPage은 부모임을 알고 있으므로 Page1/SubPage

    +0

    rarouš - 답변 해 주셔서 감사합니다. 이것은 좋은 ida이지만'{* path}'는 실제 (그리고 가상의) 파일 이름도 잡을 수 없습니까? – Venemo

    1

    패턴을 사용할 수 있습니다. "Page/{*path}" 패턴을 사용할 수 있습니다. 그런 다음 '/'의 문자열을 분할하여 경로를 분해하고 그 경로를 따라 가거나 DB에 [생성 된] 경로를 저장하고 직접 조회하는 Rarouš의 제안을 사용할 수 있습니다.

    Rarouš의 방법을 사용하는 경우 부모 경로가 변경되면 모든 하위 항목의 경로 항목을 업데이트해야합니다. 이 작업은 단일 업데이트 쿼리로 간단하게 수행 할 수 있습니다.

    설정 파일 또는 테이블 항목의 어딘가에 홈 페이지에 사용할 페이지를 매핑한다고 가정합니다. 홈 페이지 컨트롤러가 조회를 수행하고 홈 페이지보기의 컨텐츠를 반환하여 렌더링 할 수 있습니다 (공유보기, 부분보기를 사용하거나 페이지 컨트롤러를 호출하여 동작을 복제하지 않을 수 있음). 해당 페이지로 리디렉션 할 수 있습니다.

    이 기술을 사용하면 같은 방법으로 모든 페이지를 처리하는 단일 페이지 컨트롤러와보기를 가질 수 있습니다. 다른 요구 사항은 MVC 프레임 워크에 의해 자동으로 처리되는 것 같습니다.

    경로는 다음과 같이 보일 것이다 :

    http://mysite.com/Page/Page1/ 
    http://mysite.com/Page/Page1/SubPage/ 
    http://mysite.com/Page/Page/ChildPage/GrandChildPage/ 
    

    당신은 물론 "페이지"이외의 접두어를 사용할 수 있습니다.

    +0

    @Andre - 답변 해 주셔서 감사합니다. 이것은 지금까지 가장 좋은 생각입니다. :) – Venemo

    +0

    경로 항목을 가장 구체적인 것으로부터 덜 구체적으로 주문할 수 있으며 접두사를 삭제하려면 RouteTester (http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx)를 사용하여 노선. –

    +0

    http://stephenwalther.com/blog/archive/2008/08/03/asp-net-mvc-tip-29-build-a-controller-to-debug-your-custom-routes.aspx –