MVC6 中的区域路由中断

Area routing breaks in MVC6

在以前的 ASP.NET 版本中,使用 MVC 5,我可以在我的 AreaRegistraion 中设置这样的路由:

context.MapRoute(
    "pfrecent",
    "Forums/Recent/{page}",
    new { controller = ForumController.Name, action = "Recent", page = 1 },
    new[] { "PopForums.Controllers" });

这会将 /Forums/Recent 路由到论坛控制器及其最近的操作。但是,我无法弄清楚如何让它在 ASP.Net 5/MVC 6 中工作。我已经将 [Area("Forums")] 添加到控制器 class,并从 Startup class:

routes.MapRoute(
    "pfrecent",
    "Forums/Recent/{page}",
    new { controller = ForumController.Name, action = "Recent", page = 1 });
routes.MapRoute(
    name: "areaRoute",
    template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

但是,它解析为 /Forums/Forum/Recent?page=1。本意是继续使用/Forums/Recent.

将此放在您的 Startup.cs 文件中路线列表的顶部:

routes.MapRoute(
                name: "forumsAreaRoute",
                template: "Forums/{action}/{page?}",
                defaults: new {area = "Forums", controller = "Forum", action = "Recent", page = 1});

您的论坛控制器应如下所示:

[Area("Forums")]
public class ForumController : Controller
{
    // GET: /<controller>/
    public IActionResult Recent(int? page)
    {
        // Do action stuff here
    }
}

此解决方案将满足 http://somedomain.com/Forums/Recent/1 的 url 和 return 第一页。

我讨厌回答我自己的问题,但回到这个问题并查看源代码并进行试验后,我发现你必须在路由映射中指定区域,以及 HtmlHelpers(我假设这对于标签助手也是如此,但我在转换方面还没有走那么远。)因此路由映射必须如下所示:

routes.MapRoute(
    "pfrecent",
    "Forums/Recent/{page?}",
    new { controller = ForumController.Name, action = "Recent", page = 1, Area = "Forums" }
);

重要的部分是路由值对象中的区域属性。 HtmlHelper 必须看起来像这样,同时命名区域:

@Html.ActionLink(PopForums.Resources.Recent, "Recent", ForumController.Name, new { page = 1, Area = "Forums" }, null)

它导致最近页面的 URL 成为预期的 /Forums/Recent。据我所知,在 MVC5 的派生 AreaRegistration class 中设置路由会为您设置路由上的区域值。在您的控制器 class 上安装 [Area("Forums")](我已经拥有)似乎承担了以前的区域注册角色。

我们正在使用它来启用 MVC 6 中的区域:

        // Configure MVC routing
        app.UseMvc(routes =>
        {
            // Areas support
            routes.MapRoute(
                name: "areaRoute",
                template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

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

第一条路线针对区域,第二条路线针对主要内容。

在 Startup.cs

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

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

在控制器上

[Area("Business")]
public class DemoController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}