How to use an Area in ASP.NET Core

72,066

Solution 1

In order to include an Area in an ASP.NET Core app, first we need to include a conventional route in the Startup.cs file (It's best to place it before any non-area route):

In Startup.cs/Configure method:

app.UseMvc(routes =>
{
    routes.MapRoute("areaRoute", "{area:exists}/{controller=Admin}/{action=Index}/{id?}");

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

Then make a folder named Areas in the app root and make another named Admin inside the former, also make these folders inside Admin (ViewComponent is optional):

enter image description here

Now we create a controller inside the Controllers folder named AdminController, the content can be like:

[Area("Admin")]
[Route("admin")]
public class AdminController : Controller
{
    public AdminController()
    {
        // do stuff
    }

    public IActionResult Index()
    {
        return View();
    }

    [Route("[action]/{page:int?}")]
    public IActionResult Orders()
    {
        return View();
    }

    [Route("[action]")]
    public IActionResult Shop()
    {
        return View();
    }
    
    [Route("[action]/newest")]
    public IActionResult Payments()
    {
        return View();
    }
}

Now in order for that to work, you'll need to create Views for all actions that return one. The hierarchy for views is just like what you have in a non-area Views folder:

enter image description here

Now, you should be good to go!

Question: What if I want to have another controller inside my Area?

Answer:

Just add another controller beside AdminController and make sure the routes are like the following:

[Area("Admin")]
[Route("admin/[controller]")]
public class ProductsController : Controller
{
    public ProductsController()
    {
        //
    }

    [Route("{page:int?}")]
    public IActionResult Index()
    {
        return View();
    }
}

The important part is [Route("admin/[controller]")]. With that you can keep the style of routing to admin/controller/action/...

Solution 2

In ASP.NET Core 3.0. If you are working with Endpoint patterns, after adding the Area (Right click over project, Add, New Scaffolded Item, Area), you have to add manually routing pattern on startup.cs Configure method. (At this point the generated ScaffoldingReadMe.txt is out of date).

app.UseEndpoints(endpoints =>
{

    endpoints.MapAreaControllerRoute(
        "Admin",
        "Admin",
        "Admin/{controller=Home}/{action=Index}/{id?}");

    endpoints.MapControllerRoute(
         name: "default",
         pattern: "{controller=Home}/{action=Index}/{id?}");
});

Solution 3

In the Microsoft docs to migrate from ASP.NET CORE 2.2 to 3.0 the suggestion is to:

Replace UseMvc with UseEndpoints.

I encountered some challenges while trying to fix my Area's while simultaneously having Identity to keep working - but the solution below seems to be working for ASP.NET CORE 3.0 :

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapControllerRoute("areas", "{area:exists}/{controller=Home}/{action=Index}/{id?}");
    endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
});

Hopefully I could also help you out and reduce the research time :-)

Solution 4

Scaffolding has generated all the files and added the required dependencies.

However the Application's Startup code may required additional changes for things to work end to end. Add the following code to the Configure method in your Application's Startup class if not already done:

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

Solution 5

Areas Implementation in Routing First Create Area(Admin) using VS and add the following code into Startup.cs First Way to Implement:- Add Controller Login and Index Action and add Following Code, [Area(“Admin”)] is compulsory to add on controller level to perform asp.net areas Routing. Startup.cs

 app.UseMvc(routes =>
            {
                routes.MapRoute(
                  name: "areas",
                  template: "{area:exists}/{controller=Login}/{action=Index}/{id?}"
                );
            });

Note: Area routing must be placed first with non area routing, area: exists is compulsory to add area routing.

Controller Code:

[Area("Admin")] 
    public class LoginController : Controller
    {
        public IActionResult Index()
        {
            return Content("Area Admin Login Controller and Index Action");
        }
    }

This route may be called using http://localhost:111/Admin

Second Way to Implement Area Routing:- Add Following code into startup.cs.

app.UseMvc(routes =>
            {
                routes.MapAreaRoute(
    name: "default",
    areaName: "Guest",
    template: "Guest/{controller}/{action}/{id?}",
    defaults: new { controller = "GuestLogin", action = "Index" });
            });

Create an Area “Guest”, Add “GuestLogin” Controller and “Index” Action and add the following code into the newly created controller.

[Area("Guest")]
    public class GuestLoginController : Controller
    {
        public IActionResult Index()
        {
            return Content("Area Guest Login Controller and Index Action");
        }
    }

This route may be called using http://localhost:111/Guest

Share:
72,066
Vahid Amiri
Author by

Vahid Amiri

Trying to develop maintainable web and mobile apps using bleeding edge technologies (not to be confused with ones that cool kids use). I'm identified as an ENTJ person according to the Myers-Briggs Type Indicator test. I like working with php/javascript and go. I'm also fine working on macos/windows and also ios/android.

Updated on July 05, 2022

Comments

  • Vahid Amiri
    Vahid Amiri almost 2 years

    How do I use an Area in ASP.NET Core?

    I have an app that needs an Admin section. This section requires its Views to be placed in that area. All requests that start with Admin/ will need to be redirected to that area.

  • Vahid Amiri
    Vahid Amiri over 7 years
    This is tested on RC1, RC2, and 1.0. It totally works.
  • motevalizadeh
    motevalizadeh over 7 years
    I created a sample as you show above and add admin area, it works fine, but when I published my project, it doesn't published admin area and views and files, how can I handle it?
  • Vahid Amiri
    Vahid Amiri over 7 years
    @motevallizadeh, Another question of mine! stackoverflow.com/questions/37326068/…
  • motevalizadeh
    motevalizadeh over 7 years
    thanks ,In your mind. is it .net core stable to start a real/final web application?
  • Vahid Amiri
    Vahid Amiri over 7 years
    @motevallizadeh, Hosting could be an issue because you'll absolutely need a VPS or Dedicated Server as no web based control panel supports ASP.NET Core yet (Plesk will eventually support it but still no ETA). Also Check out ASP.NET Core documentation (stackoverflow.com/documentation/asp.net-core/topics), I wrote some articles about localization and authorization.
  • motevalizadeh
    motevalizadeh over 7 years
    Thanks a lot for sharing your knowledge
  • AliK
    AliK over 7 years
    I find that you still have to copy the contents css/js etc into wwwroot, is there a way around this for areas as you may have some scripts that may have some area related data that you do not wish to expose for some reason?
  • Vasiliy
    Vasiliy over 7 years
    @AliK, think to accomplish this you will need to store these scripts outside wwwroot and serve them over controller returning FileResult, as written here: docs.microsoft.com/en-us/aspnet/core/fundamentals/static-fil‌​es: "The static file module provides no authorization checks. Any files served by it, including those under wwwroot are publicly available. To serve files based on authorization: Store them outside of wwwroot and any directory accessible to the static file middleware and Serve them through a controller action, returning a FileResult where authorization is applied"
  • AliK
    AliK over 7 years
    @Vasiliy I did take a look at that option but seems a bit far fetched just to serve files required for an area that should be private in most cases, i am guessing at many people have a similar requirement so maybe someone has another solution.
  • Johan Herstad
    Johan Herstad about 7 years
    Is not the point of using Areas more to do about organization and structure, not security? Because I still don't see any other reason to use areas.
  • Lorenzo
    Lorenzo about 7 years
    @VSG24: what about if I want to create a view in the area zone that should use a shared layout in the non area zone? I have tried by creating a _ViewStart.cshtml in the area views folder with Layout = "~/Views/Shared/_LayoutAdmin.cshtml"; but unfortunately is not working
  • ArcadeRenegade
    ArcadeRenegade about 7 years
    is it possible to have different Identity auth options for a specific area? let's say, for only the "admin" area, set ApplicationCookie.AutomaticChallenge = true and ApplicationCookie.LoginPath = "admin/account/login"?
  • Sachin Pakale
    Sachin Pakale about 7 years
    This didn't work for me. I tried to code the same as you did. I am still redirected to the default view. Am i missing on something?
  • Vahid Amiri
    Vahid Amiri about 7 years
    @SachinPakale Did you include the area route in UseMvc()?
  • Sachin Pakale
    Sachin Pakale about 7 years
    This is my UseMvc code routes.MapRoute("admin", "{area:exists}/{controller=Admin}/{action=Index}/{id?}"); // Default routing routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });
  • Sachin Pakale
    Sachin Pakale about 7 years
    this worked for me [Route("")] [Route("Admin")] [Route("Admin/Index")] public IActionResult Index()
  • silkfire
    silkfire almost 7 years
    @VSG24 Could you explain what the :exists modifier does?
  • Shuaib
    Shuaib over 4 years
    This is what I was missing. This fixed the issue for me.
  • niico
    niico about 3 years
    So a registration file isn't the conventional way to do this anymore? I added the area, but it no longer creates one.