How to define an endpoint route to multiple areas
Asked Answered
W

2

12

I am trying to define a MapAreaControllerRoute() that routes to multiple Areas. In ASP.NET Core 3.0, however, there is the areaName: parameter that needs to be set, thus restricting each route to a single area. I don't understand how I can use one route that will work for multiple Areas.

I have read through many issues here on Stack Overflow, but it seems that this is a new requirement in ASP.NET Core 3.0. In ASP.NET Core <= 2.2 you could create a MapRoute() without defining a set areaName.

As it is now, in my Startup.cs, I define my endpoints as:

app.UseEndpoints(endpoints =>
{
  endpoints.MapAreaControllerRoute(
    name: "Area1",
    areaName: "Area1",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
  );

  endpoints.MapAreaControllerRoute(
    name: "Area2",
    areaName: "Area2",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
  );

  endpoints.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

});

Surely, there must be a way to define a single route to cover all Areas?

Wofford answered 12/10, 2019 at 9:40 Comment(0)
W
16

Ok, so after reading an additional bunch of links, it turns out to be a case of missing attributes for the area controllers! By tagging the controllers with the following tags:

[Area("Area1")]
[Route("Area1/[controller]/[action]")]
public class Area1Controller : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

and changing the routes to:

        app.UseEndpoints(endpoints =>
        {
                endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");

            endpoints.MapAreaControllerRoute(
                name: "areas",
                areaName: "areas",
                pattern: "{area}/{controller=Home}/{action=Index}/{id?}"
                );
    }

everything seems to work as expected.

Wofford answered 12/10, 2019 at 13:55 Comment(5)
Shouldn't the more complex route go first? I noticed you did that in your original post you have it that way but changed in the solution. The documentation for endpoint routing is still incomplete and unpublished but all previous docs suggest the previous method. so i'm curious as to why you ordered it opposite.Stun
I can't understand how your area routing can work. The auto-generate code for Net Core 3.1 is as follows. Please note the name value should be "areaRoute". app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "areaRoute", pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"); endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); });Kornher
Seems to me this is working because of the Route attribute on the Controller class only, and has nothing to do with the call to MapAreaControllerRoute(). Did you test it without that block in your Startup.cs? Edit: Why not just use MapControllerRoute() if you want to create a route that is not specific to an Area?Birth
@BobbyR. The order of the routes does not matter, at least in .NET 5. All the routes are processed, and if more than one route matches, then the most specific route is chosen. The rules for which routes are more specific are given in MSDN link learn.microsoft.com/en-us/aspnet/core/fundamentals/…Purl
At the time of my comment they were still developing the documentation for the release version in question. the available docs had some quirky info that left a ton of people unable to figure it out. They released the documentation for this version months ago and is now fairly straightforward.Stun
B
5

You can write a generic pattern for areas using MapControllerRoute():

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "areas",
        pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
    );
    endpoints.MapDefaultControllerRoute();
});

Then the area controllers just need the Area attribute:

[Area("AreaName")]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}
Birth answered 9/8, 2020 at 19:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.