Nemi Chand
Nemi Chand Nemi Chand is a C-sharp Corner MVP, Microsoft® Certified Professional,author,Speaker, senior developer and community lead. Nemi is passionate about community and all things .NET related, having worked with ASP.NET for over 7 years. Nemi is currently developing cloud-native services, using .NET Core, ASP.NET Core and Docker. He enjoys sharing his knowledge through his blog and by presenting at user groups. Nemi is excited to be a part of the .NET community. He enjoys contributing to and maintaining OSS projects, most actively helping save lives with open source software. You can find Nemi online at his blog www.nemi-chand.com and on Twitter as @nemidotnet

Creating Sub Areas In ASP.NET Core MVC

Creating Sub Areas In ASP.NET Core MVC

In this article, we’ll learn sub area, using IViewLocationExpander. IViewLocationExpander takes care to modify view locations, how the view engine searches for the path.

The source code is available @ Github

Areas are ASP.NET MVC Core features, which are used to organize the functionality into the groups. Read more about areas here.

Sub area in MVC

Steps to create the Sub area in MVC are given below.

  1. Sub area folder structure.
  2. SubArea RouteValueAttribute.
  3. SubAreaViewLocationExpander.
  4. Configure Razor View Engine option in startup class.
  5. Attribute usages.
  6. SubArea Routes.

Folder structure

Area refers to MVC features, which are used to restructure or group the functionality, separate the Controller and Views of each area. In ASP.NET Core MVC, we can create n-level of sub areas under an area.

Create the folder structure, as shown below.

Folder Structure

SubArea Attribute

It is a key-value pair RouteValueAttribute, which specifies the containing Controller or an action. This is a must to decorate the Controller with this attribute.

This is similar to an area attribute. To more about it, click here.

The route key is fixed for subarea routes and route value changes as sub area is requested. This attribute usage is restricted to a class and a method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/// <summary>  
    /// this is simillar to this https://github.com/aspnet/AspNetCore/blob/master/src/Mvc/Mvc.Core/src/AreaAttribute.cs  
    /// </summary>  
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]  
    public class SubAreaAttribute : RouteValueAttribute  
    {  
        public SubAreaAttribute(string subAreaName)  
            : base("subarea", subAreaName)  
        {  
            if (string.IsNullOrEmpty(subAreaName))  
            {  
                throw new ArgumentException("Sub area name cannot be null or empty", nameof(subAreaName));  
            }  
        }  
    }  

Sub Area View location Expander

This is implementing the IViewLocationExpander interface to expand the sub area view location. You can set view location. The route key is set to subarea and gets the same key value from RazorviewEngine, which routes to place in runtime location path. View engine string format follows as {0} –> action Name , {1} –> Controller name and {2} –> name of the area, if it exists. The order of view locations matters because the engine search for the path is added into the order.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/// <summary>  
    /// sub area view location expander  
    /// </summary>  
    public class SubAreaViewLocationExpander : IViewLocationExpander  
    {  
        private const string _subArea = "subarea";  
  
        public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, 
            IEnumerable<string> viewLocations)  
        {  
            //check if subarea key contain  
            if (context.ActionContext.RouteData.Values.ContainsKey(_subArea))  
            {  
                string subArea = RazorViewEngine.GetNormalizedRouteValue(context.ActionContext, _subArea);  
                IEnumerable<string> subAreaViewLocation = new string[]  
                {  
                "/Areas/{2}/SubAreas/"+subArea+"/Views/{1}/{0}.cshtml"  
                };  
  
                viewLocations = subAreaViewLocation.Concat(viewLocations);  
  
            }  
  
            return viewLocations;  
        }  
  
        public void PopulateValues(ViewLocationExpanderContext context)  
        {  
            string subArea = string.Empty;  
            context.ActionContext.ActionDescriptor.RouteValues.TryGetValue(_subArea, out subArea);  
  
            context.Values[_subArea] = subArea;  
        }  

Configure Razor View Options

In the startup class, you have to configure Razor view engine options in Configure Services method.

1
2
3
4
services.Configure<RazorViewEngineOptions>(o => 
{  
    o.ViewLocationExpanders.Add(new SubAreaViewLocationExpander());  
});

Attribute usages in Controller

Just decorate your Controller with an area and subarea attribute.

1
2
3
4
5
6
7
8
9
10
11
[Area("Department")]  
[SubArea("IT")]  
public class HomeController: Controller {  
    /// <summary>    
    /// GET /Department/IT/Home/Index    
    /// </summary>    
    /// <returns></returns>    
    public IActionResult Index() {  
        return View();  
    }  
} 

Routes

Route key is for sub area, which is similar to an area route. Sub area route key will be same in view location expander.

1
2
3
4
5
6
7
8
9
10
11
12
13
app.UseMvc(routes =>    
    {    
        routes.MapRoute(    
            name: "subAreaRoute",    
            template: "{area:exists}/{subarea:exists}/{controller=Home}/{action=Index}/{id?}");    
        routes.MapRoute(    
            name: "areaRoute",    
            template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");    
        routes.MapRoute(    
            name: "default",    
            template: "{controller=Home}/{action=Index}/{id?}");    

    });

Demo Screens

Department Area screen
1
//GET Deparment/Home/Index

Deparment area

IT Sub-Area screen
1
//GET Deparment/IT/Home/Index

IT Sub Area

Marketing Sub-Area screen
1
//GET Deparment/Marketing/Home/Index

Marketing sub area

The source code is available @ GitHub

In this article you have learned how you can create a sub area under the area with n-level. IViewLocationExpander helps to modify the view location paths.

comments powered by Disqus