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.
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. 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.
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?}"
);
}
// Assume you have an Admin area under /Areas/Admin
namespace DL.SO.Web.UI.Areas.Admin.Controllers
{
[Area("admin")]
public abstract class AdminControllerBase : Controller
{
}
}
// 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();
}
}
}
// 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.