简体   繁体   中英

ASP.Net MVC Core 2 - Area Routing

I'm trying to implement an Area for Administrators within my ASP.Net MVC Core 2 application.

I have configured the route for the area as follows:

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

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

This all works pretty well.

This Admin area uses the same Layout as the main website albeit that the _ViewStart.cshtml lives in the Areas/Admin/Views directory but this still works fine.

The issue I'm having is with a navigation menu component which lives in the main site layout file and the href links in all anchors pointing to the wrong URL when inside the Admin area.

Say I have the following links:

<a asp-controller="Account" asp-action="Index">My Account</a>
<a asp-controller="Shopping" asp-action="Basket">Shopping Basket</a>
<a asp-controller="Admin" asp-action="Users">Manage Users</a>

When inside the Admin area, the links are now relative to the area and thus appear as if they were as follows:

http://localhost/Admin/Account/Index
http://localhost/Admin/Shopping/Basket
http://localhost/Admin/Admin/Users

Is there any nice way to make all of these links relative to the site root?

There are couple issues how you set things up in your application.

  1. You can't use app.UseMvc() twice. I think basically the last one will override your first setup. That's why you are seeing all links have /admin area prefix.
  2. When you want to generate a link to your user management under admin area, you should use asp-area instead, like <a asp-area="admin" asp-controller="users" asp-action="index">Manage Users</a> .

This is how I will setup areas.

Setup area route as well as the default route in Startup

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // The area routing setup has to come before your default routing!
    // Remember the order of these setups is very important!
    // Mvc will use that template as soon as it finds a matching! 

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

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

Setup an admin base controller with [Area] annotation so that you don't have to specify that in all other controllers that should be under the admin area.

// Assume you have an Admin area under /Areas/Admin

namespace DL.SO.Web.UI.Areas.Admin.Controllers
{
    [Area("admin")]
    public abstract class AdminControllerBase : Controller
    {
    }
}

Controllers under admin area

// Dashboard controller. I know you have home controller inside 
// your admin area but they should work the same.

namespace DL.SO.Web.UI.Areas.Admin.Controllers
{
    public class DashboardController : AdminControllerBase
    {
        public IActionResult Index()
        {
           return View();
        }
    }
}

// Users controller. I know you have User(s) controller but I usually
// just keep the name of the controller singular.

namespace DL.SO.Web.UI.Areas.Admin.Controllers
{
    public class UserController : AdminControllerBase
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

Specify the area with anchor tag helper

// My habit is to always specify the area with the anchor tag helper.
// For public links (those are not under any areas):
//     I just pass empty string, like asp-area=""
// For links pointing to any controller under any area:
//     Just pass the area, like asp-area="admin"

// http://localhost/account
<a asp-area="" asp-controller="account" asp-action="index">My Account</a>

// http://localhost/shopping/basket
<a asp-area="" asp-controller="shopping" asp-action="basket">Shopping Basket</a>

// http://localhost/admin/user
<a asp-area="admin" asp-controller="user" asp-action="index">Manage Users</a>

// http://localhost/admin/dashboard
<a asp-area="admin" asp-controller="dashboard" asp-action="index">Admin Panel</a>

You can edit the template for the URL to be displayed as preferred. ie change to

    template: "{controller=Home}/{action=Index}/{id?}");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM