Wednesday, December 8, 2010

ASP.NET MVC Areas 이용시, 동일한 Controller 이름으로 인한 문제

가령 쇼핑몰에서 관리자용 서비스와 파트너사를 위한 별도의 Areas를 구성했다고 하자. 이 경우 사용자, 관리자 그리고 파트너 별로 별도의 Home Controller를 가진다고 하자. 물론 사용자의 경우 Home, 관리자의 경우 Admin 그리고 파트너의 경우 Partenr로 시작 컨트롤러를 라우트에 설정할 수는 있겠으나, 특정 엔터티와 관련되어 CRUD 작업을 하게되는 컨트롤러의 이름을 각각 지정하기란 그리 명료하지도 않고 오히려 혼란을 초래할 수 있다.

예를 들어 상품에 관한 엔터티의 경우 사용자는 조회작업을 하게될테고, 관리자의 경우 전체 상품에 관한 관리를 하게 된다. 그리고 파트너의 경우 자신이 직접 등록한 상품에 대해서 관리를 하게된다고 보자. 여기에 관련된 컨트롤러 이름을 ItemController라고 하면, 각 Areas별로 이러한 중복된 이름의 Controller가 존재하게 될것이다. 이러한 경우에도 각각 별도의 명명을 붙인다면, 그리고 이러한 경우의 컨트롤러가 많아진다면… 분명 혼란스러울테고, 명명법 측면에서도 그리 바람직하지 않으리라 본다.

시작 페이지의 경우 HomeController가 서비스 루트와 그리고 각각의 Areas 마다 존재하게 될것이다. 이 경우 아래와 같은 오류를 만나게 된다.

이름이 ‘Home’인 컨트롤러와 일치하는 여러 형식이 있습니다. 이 요청을 서비스하는 경로(‘{controller}/{action}/{id}’)에서 요청과 일치하는 컨트롤러를 검색하기 위해 네임스페이스를 지정하지 않은 경우 발생할 수 있습니다. 이 경우에는 ‘namespaces’ 매개 변수를 가지는 ‘MapRoute’ 메서드의 오버로드를 호출하여 이 경로를 등록합니다.’Home’에 대한 요청에서 다음과 같은 일치하는 컨트롤러를 찾았습니다. 

Shop.Controllers.HomeController
Shop.Areas.Partner.Controllers.HomeController
Shop.Areas.Admin.Controllers.HomeController

즉, Home을 처리하는 컨트롤러가 3군데 있는데 모호하다 이거다. 이 문제를 해결하기 위해 메시지에 나온것 처럼 네임스페이스를 등록하여 전달할 컨트롤러를 제한할 수 있다. 우선 기존의 MapRoute 등록코드 부터 보면…

routes.MapRoute(
"Default"// 경로 이름
"{controller}/{action}/{id}"// 매개 변수가 있는 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 매개 변수 기본값
);

그리고 MapRoute 오버로드된 인수를 살펴보다보면 다음과 같은 녀석이 있다.

마지막 파라메터를 보면 문자형 배열로 네임스페이스를 전달 할 수 있다는걸 알 수 있다. 전달해보자면…

routes.MapRoute(
"Default"// 경로 이름
"{controller}/{action}/{id}"// 매개 변수가 있는 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // 매개 변수 기본값
new[] { "Shop.Controllers"}
);

이렇게 작성하고 빌드 후 실행시켜 보면… 정상적으로 렌더링된 첫 페이지를 만날 수 있다.

참조

Notes