问题
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?
回答1:
There are couple issues how you set things up in your application.
- 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. - When you want to generate a link to your user management under
admin
area, you should useasp-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>
回答2:
You can edit the template for the URL to be displayed as preferred. i.e. change to
template: "{controller=Home}/{action=Index}/{id?}");
来源:https://stackoverflow.com/questions/50375752/asp-net-mvc-core-2-area-routing