Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ASP.NET Core 2.0 MVC Areas

0.00/5 (No votes)
28 Aug 2017 1  
How to structure a large ASP.NET Core MVC application into logical groupings. Continue reading...

Problem

How to structure a large ASP.NET Core MVC application into logical groupings.

Solution

In an empty project, update Startup class to add services and middleware for MVC:

public void ConfigureServices(
            IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(
            IApplicationBuilder app, 
            IHostingEnvironment env)
        {
            app.UseDeveloperExceptionPage();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "area",
                    template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

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

Create a folder structure like:

Add files to Controllers and Views folders (Area1 shows below):

Add [Area] attribute to controllers in Area1 and Area2 folder:

[Area("Area1")]
    public class HomeController : Controller

    [Area("Area2")]
    public class HomeController : Controller

Discussion

MVC separate application concerns using Models, Views and Controllers. For larger applications, Areas provide a way to group these three concerns into another high level grouping. For instance, you may want to split your application into modules, each one containing its own MVC structure.

For routing purposes, there is another route parameter area available (in addition to controller and action). You could think of areas as namespaces, under which controllers live. The area route parameter is also available as ambient value if it’s in context of current request, see Routing. Below, you can see how area parameter for Area1 links is left out, since this page is in Area1 (see also Link Generation section below):

<p><strong>You are here: </strong>Area1/Home/Index</p>

<a asp-area="" asp-controller="Home" 

asp-action="Index">Home/Index</a>
<a asp-area="" asp-controller="Home" 

asp-action="About">Home/About</a>
<a asp-controller="Home" 

asp-action="Index">Area1/Home/Index</a>
<a asp-controller="Home" 

asp-action="About">Area1/Home/About</a>
<a asp-area="Area2" asp-controller="Home" 

asp-action="Index">Area2/Home/Index</a>
<a asp-area="Area2" asp-controller="Home" 

asp-action="About">Area2/Home/About</a>

In order to use Areas in your project, you first setup a folder structure with Areas root folder and sub-folders for each area (along with its controller, models and views). Note that the folder structure is important for views because MVC will search for the views in the following sequence:

Once the folder structure is in place, you can decorate controllers with [Area] attribute:

[Area("Area1")]
    public class HomeController : Controller

Link Generation

Below is a table of route parameters required when generating a link from one location to a different location, location being {area}/{controller}/{action}:

Missing route parameters mean that MVC will pick those values up from the request context. I personally find it easier to specify all the route parameters to make maintenance easier. The sample for this post has links on various pages to show how ambient values work:

Layout Pages

Razor pages inside Areas folder can use the Layout page located outside it (e.g. in /Views/Shared folder). You can define a separate Layout page for each Area too. Yet another approach is to define a common Layout page outside Areas folder and Layout pages inside Areas folder use them as their layout, creating a nested Layout page structure. Below is a Layout page for Area2 that uses shared layout page (note you need an absolute path to shared layout):

@{ 
    Layout = "/Views/Shared/_Layout.cshtml";
}

<div>
    <nav style="background-color: lightgray">
        <h2>Area2 Layout</h2>
    </nav>
    @RenderBody()
</div>

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here