Areas¶

By Dhananjay Kumar and Rick Anderson

Areas provide a way to partition a large ASP.NET Core MVC Web app into smaller functional groupings. An area is effectively an MVC structure inside an application. In an MVC project, logical components like Model, Controller, and View are kept in different folders, and MVC uses naming conventions to create the relationship between these components. For a large app, it may be advantageous to partition the app into separate high level areas of functionality. For instance, an e-commerce app with multiple business units, such as checkout, billing, and search etc. Each of these units have their own logical component views, controllers, and models. In this scenario, you can use Areas to physically partition the business components in the same project.

An area can be defined as smaller functional units in an ASP.NET Core MVC project with its own set of controllers, views, and models.

Consider using Areas in an MVC project when:

  • Your application is made of multiple high-level functional components that should be logically separated
  • You want to partition your MVC project so that each functional area can be worked on independently

Area features:

  • An ASP.NET Core MVC app can have any number of areas
  • Each area has its own controllers, models, and views
  • Allows you to organize large MVC projects into multiple high-level components that can be worked on independently

Let’s take a look at an example to illustrate how Areas are created and used. Let’s say you have a store app that has two distinct groupings of controllers and views: Products and Services. A typical folder structure for that using MVC areas looks like below:

  • Project name
    • Areas
      • Products
        • Controllers
          • HomeController.cs
          • ManageController.cs
        • Views
          • Home
            • Index.cshtml
          • Manage
            • Index.cshtml
      • Services
        • Controllers
          • HomeController.cs
        • Views
          • Home
            • Index.cshtml

When MVC tries to render a view in an Area, by default, it tries to look in the following locations:

/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml

These are the default locations which can be changed via the AreaViewLocationFormats on the Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions.

For example, in the below code instead of having the folder name as ‘Areas’, it has been changed to ‘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");
});

One thing to note is that the structure of the Views folder is the only one which is considered important here and the content of the rest of the folders like Controllers and Models does not matter. For example, you need not have a Controllers and Models folder at all. This works because the content of Controllers and Models is just code which gets compiled into a .dll where as the content of the Views is not until a request to that view has been made.

Once you’ve defined the folder hierarchy, you need to tell MVC that each controller is associated with an area. You do that by decorating the controller name with the [Area] attribute.

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

Set up a route definition that works with your newly created areas. The 🔧 Routing to Controller Actions article goes into detail about how to create route definitions, including using conventional routes versus attribute routes. In this example, we’ll use a conventional route. To do so, open the Startup.cs file and modify it by adding the highlighted route definition below.

...
app.UseMvc(routes =>
{
  routes.MapRoute(name: "areaRoute",
    template: "{area:exists}/{controller=Home}/{action=Index}");

  routes.MapRoute(
      name: "default",
      template: "{controller=Home}/{action=Index}");
});

Browsing to http://<yourApp>/products, the Index action method of the HomeController in the Products area will be invoked.

Publishing Areas¶

To publish all views of the areas folder, in the project.json file include an entry in the publishOptions‘s include node like below:

"publishOptions": {
  "include": [
    "Areas/**/*.cshtml",
    ....
    ....
  ]