2009-04-10 4 views
2

asp.net mvc에서 동일한 개체/모델에 대한 컨트롤러 및보기가 두 개 이상 필요했지만 예상보다 조금 복잡했습니다.컨트롤러 및 뷰의 하위 폴더

 
site.com/product 
    -> will show product details to visitors. 

site.com/admin/product 
    -> will show some extra information together with product details. 
     and some commands like delete, edit etc. 

목표는 방문자와 관리자를위한 URL을 분리해서하는 것입니다

기본적으로 내가하고 싶은 것은이 같은 것입니다.

 
> Controllers 
    > Admin 
     ProductController.cs 
    ProductController.cs 
> Views 
    > Admin 
     > Product 
      Index.aspx 
    > Product 
     Index.aspx 

내가 문제없이 올바른 컨트롤러에 URL을 매핑 할 수 있습니다 :

내 첫 번째 방법은이 방법을 내가 컨트롤러와 뷰 폴더의 하위 폴더를 만들 것, 그래서 일을 볼 것이라고했다 (클래스 네임이 같기 때문에 네임 스페이스를 지정했다면). 그러나 관리자 폴더의 컨트롤러에서보기를 반환하면보기/관리자/제품 폴더 아래의 인덱스보기가 아니라보기/제품 아래의보기가 표시됩니다.

내가 알 수있는 말은 내가 알 수있는 return View("Full path here") 내가 원하는보기를 반환합니다. 그러나 그것은 분명히 좋은 해결책이 아니며 그렇게하고 싶지 않습니다.

내 질문은 이런 상황을 처리하는 가장 좋은 방법은 무엇이며, 그 조건은 URL이어야합니다.

  • 뷰 방식 (또는 이러한 목적을 위해 오버라이드 (override) 할 필요가 다른 사람을) 무시하고 올바른 뷰가 반환됩니다 확인합니다 사용자 정의 컨트롤러 클래스 만들기?

    • 이 하나는 못생긴 해킹이지만 작동합니다.
  • 폴더를 고려한 사용자 지정보기 엔진을 만드시겠습니까?

    • 내가 정확히 내가이 작업을 수행 할 수 있는지 모르겠지만, 지금까지 내가 이해,이 또한 문제
  • 사용 Phil HaackAreas Prototype를 해결해야합니까?

    • 이것은 실제로 폴더에 대해 다른 레이아웃을 사용하지만, 이론적으로는 이것도 작동해야합니다. 그러나이 방법을 사용하는 것이 가장 좋은 방법인지 확실하지 않습니다. 다른 컨트롤러 &을 사이트의 다른 부분에 배치하면 원하는 내용이 정확하지 않기 때문입니다.

I의 의견을 반환 할 때 고려 사항으로 폴더를 취 사용자 지정보기 엔진 생각,쪽으로 기울고 있어요,하지만 내가 말했듯이, 나는 그렇게하는 방법을 모르겠어요.

제안 사항?

답변

1

ASP.Net MVC는 기본적으로 평면 뷰 폴더 구조를 사용합니다. 지역은 어느 정도 도움이 될 수 있습니다.

이렇게하면 깊게 중첩 된 컨트롤러 계층 구조에 대한보기를 관리하기가 어려워 질 수 있습니다. 여기서 실제로 원하는 것은 Views 폴더 계층 구조가 컨트롤러의 네임 스페이스 계층 구조와 일치하도록하는 것입니다.

좋은 소식은 놀랍지 만 조금도 노력하지 않고 사용자 정의 ViewEngine을 작성할 수 있다는 것입니다. 자세한 내용은 ControllerPathViewEngine project on GitHub을 참조하십시오.

어떻게 작동하는지 설명하기 위해 ControllerPathRazorViewEngine 클래스의 스 니펫을 포함 시켰습니다. FindView/FindPartialView 메서드를 가로 채고 컨트롤러 이름을 컨트롤러 네임 스페이스 및 이름을 기반으로하는 폴더 경로로 바꾸면 기본 Views 폴더 내의 중첩 폴더에서 뷰를로드 할 수 있습니다.

public class ControllerPathRazorViewEngine : RazorViewEngine 
    { 
     //... constructors etc. 

     public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) 
     { 
      return FindUsingControllerPath(controllerContext,() => base.FindView(controllerContext, viewName, masterName, useCache)); 
     } 

     public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) 
     { 
      return FindUsingControllerPath(controllerContext,() => base.FindPartialView(controllerContext, partialViewName, useCache)); 
     } 

     private ViewEngineResult FindUsingControllerPath(ControllerContext controllerContext, Func<ViewEngineResult> func) 
     { 
      string controllerName = controllerContext.RouteData.GetRequiredString("controller"); 
      string controllerPath = controllerPathResolver.GetPath(controllerContext.Controller.GetType()); 
      controllerContext.RouteData.Values["controller"] = controllerPath; 
      var result = func(); 
      controllerContext.RouteData.Values["controller"] = controllerName; 
      return result; 
     } 
    } 
관련 문제