본 번역문서는 개인적인 취지로 번역되어 제공되는 문서로, 원문을 비롯한 모든 저작권은 마이크로소프트사에 있습니다. 마이크로소프트사의 요청이 있을 경우, 언제라도 게시가 중단될 수 있습니다. 본 번역문서에는 오역이 포함되어 있을 수 있으며 주석도 번역자 개인의 견해일뿐입니다. 마이크로소프트사는 본 문서의 번역된 내용에 대해 일체의 보장을 하지 않습니다. 번역이 완료된 뒤에도 제품이 업그레이드 되거나 기능이 변경됨에 따라 원문도 변경되거나 보완되었을 수 있으므로 참고하시기 바랍니다.
원문: https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/areas
영역
영역(Areas)은 관련된 기능들을 분리된 이름공간(라우팅)과 폴더 구조(뷰)의 그룹으로 분할 구성하는 용도로 사용되는 ASP.NET MVC의 기능입니다.
영역을 사용하면 controller
와 action
에 더하여 area
라는 또 다른 라우트 매개변수가 추가됨으로써, 라우팅에 대한 계층구조가 만들어집니다.
영역을 사용하면 규모가 큰 ASP.NET Core MVC 응용 프로그램을 보다 작은 여러 개의 기능적 그룹으로 분할할 수 있습니다.
영역은 응용 프로그램 내부의 MVC 구조에 효과적입니다.
MVC 프로젝트에서 모델, 컨트롤러, 뷰 같은 논리적 구성 요소들은 각기 다른 폴더에 위치하며, MVC는 명명 규칙을 통해서 이런 구성 요소들 간의 관계를 수립합니다.
규모가 큰 응용 프로그램에서는 응용 프로그램을 서로 분리된 고수준의 기능적 영역으로 분할하는 편이 유리합니다.
한 가지 예로, 지불, 결제, 검색 등과 같은 여러가지 업무 단위로 구상된 전자상거래 응용 프로그램을 들 수 있습니다.
이런 각각의 업무 단위들은 자체적인 논리적 구성 요소들, 즉 뷰, 컨트롤러, 모델을 갖습니다.
이런 시나리오에서 영역을 사용하면 동일한 프로젝트 내의 업무 구성 요소들을 물리적으로 분리할 수 있습니다.
영역은 자체적인 컨트롤러, 뷰, 모델들의 모음을 갖고 있는 ASP.NET Core MVC 프로젝트 내부의 보다 작은 기능적 단위라고 정의할 수 있습니다.
다음과 같은 경우, MVC 프로젝트에서 영역을 사용할 것을 고려해보시기 바랍니다:
-
응용 프로그램이 논리적으로 분리 가능한 여러 개의 고수준 기능적 구성 요소들로 구성된 경우
-
내부적으로 MVC 프로젝트를 분리해서 각 기능적 영역들이 독립적으로 동작할 수 있게 만들고자 하는 경우
영역의 기능:
-
ASP.NET Core MVC 응용 프로그램은 필요한 만큼 얼마든지 영역을 가질 수 있습니다.
-
각 영역은 자체적으로 컨트롤러, 모델, 뷰를 갖습니다.
-
큰 규모의 MVC 프로젝트를 독립적으로 동작할 수 있는 여러 개의 고수준 구성 요소들로 구성할 수 있습니다.
-
서로 다른 영역에 존재하는, 동일한 이름을 가진 여러 개의 컨트롤러들을 지원합니다.
간단한 예제를 통해서 영역을 생성하고 사용하는 방법을 살펴보도록 하겠습니다.
Products와 Services라는 개별적인 두 그룹의 컨트롤러 및 뷰들이 존재하는 상점 응용 프로그램을 가정해봅니다.
영역 기능을 사용하는 MVC 프로젝트의 일반적인 폴더 구조는 다음과 같습니다:
-
프로젝트명
-
Areas
-
Products
-
Controllers
- HomeController.cs
- ManageController.cs
-
Views
-
Services
영역 기능을 사용하는 경우, MVC는 뷰를 렌더하기 위해서 기본적으로 다음과 같은 경로들을 검색합니다:
/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml
이 경로들은 기본 위치로, Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions
클래스의 AreaViewLocationFormats
속성을 이용해서 변경할 수 있습니다.
가령, 다음 예제 코드는 'Areas'라는 폴더명 대신, 'Categories' 라는 폴더명을 사용하도록 구성합니다.
services.Configure<RazorViewEngineOptions>(options =>
{
options.AreaViewLocationFormats.Clear();
options.AreaViewLocationFormats.Add("/Categories/{2}/Views/{1}/{0}.cshtml");
options.AreaViewLocationFormats.Add("/Categories/{2}/Views/Shared/{0}.cshtml");
options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
});
여기서 한 가지 유의해야 할 점은, 이 중 Views 폴더의 구조만 유의해서 관리하면 되며, Controllers 폴더나 Models 폴더 같은 나머지 폴더들의 내용은 별다른 문제가 되지 않는다는 것입니다.
단적으로 Controllers 폴더나 Models 폴더는 아예 존재하지 않아도 무방합니다.
그 이유는 Controllers 폴더와 Models 폴더의 내용들은 그저 .dll 파일로 컴파일되는 코드인 반면, Views 폴더의 내용들은 해당 뷰가 요청되기 전까지는 컴파일되지 않기 때문입니다.
폴더의 계층 구조를 정의한 다음에는, MVC에게 각 영역에 속한 컨트롤러들을 알려줘야 합니다.
이 작업은 컨트롤러에 [Area]
어트리뷰트를 적용해서 처리할 수 있습니다.
...
namespace MyStore.Areas.Products.Controllers
{
[Area("Products")]
public class HomeController : Controller
{
// GET: /Products/Home/Index
public IActionResult Index()
{
return View();
}
// GET: /Products/Home/Create
public IActionResult Create()
{
return View();
}
}
}
계속해서 이번에는 새로 생성한 영역에 적용할 라우트 정의를 설정합니다.
컨트롤러 액션 라우팅하기 문서에서는 기본 라우트 및 어트리뷰트 라우트의 이용해서 라우트 정의를 생성하는 방법을 자세하게 설명합니다.
본문의 예제에서는 기본 라우트 방식을 사용합니다.
따라서, Startup.cs 파일을 열고 다음 코드에 강조된 라우트 정의를 추가합니다.
...
app.UseMvc(routes =>
{
routes.MapRoute(name: "areaRoute",
template: "{area:exists}/{controller=Home}/{action=Index}");
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}");
});
이제 http://<yourApp>/products로 이동해보면, Products
영역에 위치한 HomeController
의 Index
액션 메서드가 호출될 것입니다.
링크 생성
-
영역 기반 컨트롤러에 존재하는 액션에서 동일한 컨트롤러의 다른 액션을 가리키는 링크 생성하기
현재 요청의 경로는 /Products/Home/Create
라고 가정합니다.
HtmlHelper 구문: @Html.ActionLink("Go to Product's Home Page", "Index")
TagHelper 구문: <a asp-action="Index">Go to Product's Home Page</a>
이 경우, 'area' 값과 'controller' 값은 현재 요청의 컨텍스트를 통해서 이미 사용 가능하기 때문에 명시적으로 제공할 필요가 없다는 점에 주목하시기 바랍니다.
이런 유형의 값을 주변값(Ambient Values)이라고 합니다.
-
영역 기반 컨트롤러에 존재하는 액션에서 다른 컨트롤러의 특정 액션을 가리키는 링크 생성하기
현재 요청의 경로는 /Products/Home/Create
라고 가정합니다.
HtmlHelper 구문: @Html.ActionLink("Go to Manage Products' Home Page", "Index", "Manage")
TagHelper 구문: <a asp-controller="Manage" asp-action="Index">Go to Manage Products' Home Page</a>
이번에는 'area' 값은 주변값이 사용됐지만, 'controller' 값은 명시적으로 지정되었다는 점에 유의하시기 바랍니다.
-
영역 기반 컨트롤러에 존재하는 액션에서 다른 영역의 다른 컨트롤러의 특정 액션을 가리키는 링크 생성하기
현재 요청의 경로는 /Products/Home/Create
라고 가정합니다.
HtmlHelper 구문: @Html.ActionLink("Go to Services' Home Page", "Index", "Home", new { area = "Services" })
TagHelper 구문: <a asp-area="Services" asp-controller="Home" asp-action="Index">Go to Services' Home Page</a>
이번에는 주변값이 전혀 사용되지 않았습니다.
-
영역 기반 컨트롤러에 존재하는 액션에서 영역에 속하지 않은 다른 컨트롤러의 특정 액션을 가리키는 링크 생성하기
HtmlHelper 구문: @Html.ActionLink("Go to Manage Products' Home Page", "Index", "Home", new { area = "" })
TagHelper 구문: <a asp-area="" asp-controller="Manage" asp-action="Index">Go to Manage Products' Home Page</a>
이처럼 영역에 속하지 않은 컨트롤러의 액션을 가리키는 링크를 생성할 때는 빈 문자로 'area'의 주변값을 비워줘야 합니다.
영역 게시하기
영역 폴더의 모든 뷰들을 게시하려면, project.json
파일에서 publishOptions
하위의 include
노드에 다음과 같은 항목을 추가합니다:
"publishOptions": {
"include": [
"Areas/**/*.cshtml",
....
....
]