ASP.Net 没有带默认路由的 AreaAttribute 的核心区域路由
ASP.Net Core Area Routing without AreaAttribute with default routes
我的 ASP.Net 核心 MVC 项目中有关于 AreaRouting 的问题。我想在不为每个控制器添加 AreaAttribute 的情况下使用 Area 路由(我从现有的 ASP.NET MVC 5 项目中移出数百个控制器并添加此属性真的很麻烦)
我的示例应用程序文件夹结构如下所示:
命名空间遵循文件夹结构。
我找到了一种添加自定义约定并提取区域名称的方法:
internal sealed class AreaRoutingConvention : IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
var hasRouteAttributes = controller.Selectors.Any(selector => selector.AttributeRouteModel != null);
if (hasRouteAttributes)
{
return;
}
var controllerTypeNamespace = controller.ControllerType.Namespace;
if (controllerTypeNamespace == null)
return;
var areaName = controllerTypeNamespace.Split('.').SkipWhile(segment => segment != "Areas").Skip(1).FirstOrDefault();
if (!string.IsNullOrEmpty(areaName))
{
var template = areaName + "/[controller]/[action]/{id?}";
controller.RouteValues.Add("area", areaName);
foreach (var selector in controller.Selectors)
{
selector.AttributeRouteModel = new AttributeRouteModel
{
Template = template
};
}
}
}
}
我的示例路由配置是这个:
app.UseEndpoints(endpoints =>
{
endpoints.MapAreaControllerRoute(
name: "Activity_default",
areaName: "Activity",
"Activity/{controller=Activity}/{action=Index}/{id?}",
defaults: new { controller = "Activity", action = "Index" }
);
endpoints.MapAreaControllerRoute(
name: "Admin_default",
areaName: "Admin",
"Admin/{controller=Admin}/{action=Index}/{id?}",
defaults: new { controller = "Admin", action = "Index" }
);
endpoints.MapAreaControllerRoute(
name: "home_default",
areaName: "Home",
pattern: "{area}/{controller=Home}/{action=Index}/{id?}");
});
它几乎适用于我的所有情况:
现在当我输入
- /Activity/Activity/Index -> Index 方法被调用
- /Activity/Home/Index -> 未找到,如预期的那样
- /Home/Home/Index -> Index 方法被调用
- /Home/Activity/Index -> 未找到,如预期
- /Admin/Admin/Index -> Index 方法被调用
- /Admin/Activity/Index -> 未找到,如预期的那样
但我也想在用户输入
时路由到/Activity/Activity/Index方法
- /Activity
- /Activity/Activit/
有人可以帮忙解决这个问题吗?当我不使用我的自定义约定并将区域属性添加到控制器时,一切正常。
你可以试试路由属性
public partial class ActivityController : Controller
{
[Route("~/Activity")]
[Route("~/Activity/Activity")]
[Route("~/Activity/Activity/Index")]
public ActionResult Index()
{
....
}
我的 ASP.Net 核心 MVC 项目中有关于 AreaRouting 的问题。我想在不为每个控制器添加 AreaAttribute 的情况下使用 Area 路由(我从现有的 ASP.NET MVC 5 项目中移出数百个控制器并添加此属性真的很麻烦)
我的示例应用程序文件夹结构如下所示:
命名空间遵循文件夹结构。 我找到了一种添加自定义约定并提取区域名称的方法:
internal sealed class AreaRoutingConvention : IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
var hasRouteAttributes = controller.Selectors.Any(selector => selector.AttributeRouteModel != null);
if (hasRouteAttributes)
{
return;
}
var controllerTypeNamespace = controller.ControllerType.Namespace;
if (controllerTypeNamespace == null)
return;
var areaName = controllerTypeNamespace.Split('.').SkipWhile(segment => segment != "Areas").Skip(1).FirstOrDefault();
if (!string.IsNullOrEmpty(areaName))
{
var template = areaName + "/[controller]/[action]/{id?}";
controller.RouteValues.Add("area", areaName);
foreach (var selector in controller.Selectors)
{
selector.AttributeRouteModel = new AttributeRouteModel
{
Template = template
};
}
}
}
}
我的示例路由配置是这个:
app.UseEndpoints(endpoints =>
{
endpoints.MapAreaControllerRoute(
name: "Activity_default",
areaName: "Activity",
"Activity/{controller=Activity}/{action=Index}/{id?}",
defaults: new { controller = "Activity", action = "Index" }
);
endpoints.MapAreaControllerRoute(
name: "Admin_default",
areaName: "Admin",
"Admin/{controller=Admin}/{action=Index}/{id?}",
defaults: new { controller = "Admin", action = "Index" }
);
endpoints.MapAreaControllerRoute(
name: "home_default",
areaName: "Home",
pattern: "{area}/{controller=Home}/{action=Index}/{id?}");
});
它几乎适用于我的所有情况: 现在当我输入
- /Activity/Activity/Index -> Index 方法被调用
- /Activity/Home/Index -> 未找到,如预期的那样
- /Home/Home/Index -> Index 方法被调用
- /Home/Activity/Index -> 未找到,如预期
- /Admin/Admin/Index -> Index 方法被调用
- /Admin/Activity/Index -> 未找到,如预期的那样
但我也想在用户输入
时路由到/Activity/Activity/Index方法- /Activity
- /Activity/Activit/
有人可以帮忙解决这个问题吗?当我不使用我的自定义约定并将区域属性添加到控制器时,一切正常。
你可以试试路由属性
public partial class ActivityController : Controller
{
[Route("~/Activity")]
[Route("~/Activity/Activity")]
[Route("~/Activity/Activity/Index")]
public ActionResult Index()
{
....
}