Correct way of setting up routing in ASP.NET Core 5 - endpoint routing patterns get ignored

Pawel Kosinski 21 Reputation points
2021-11-02T17:19:27.137+00:00

Hi Guys,

I have a problem with routing in my application. Basically I set up my endpoint routing in Startup.cs but it always gets ignored. The patterns simply do not change anything and I am forced to use attribute routing.

If I do not use the attribute routing I get absolutely random results for top level controllers (those not in the Areas), as if patters were being matched against random controllers. For example I press Edit button in one of the views from a Controller1 (the URL is correct, has correct action and all) and page from a Controller2 opens or I get null exception error (because a random page from another controller got matched - another top level controller).

Here are the patterns I am using:

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapControllerRoute(
                    name: "areaRoute",
                    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
                endpoints.MapHub<ChatHub>("/chatHub");
                endpoints.MapHub<DeviceStatusHub>("/deviceStatusHub");
            });

I have also tried:

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

But unless I put attribute routing in my controllers (both 'top level' and ones in areas) I get the aforementioned randomness or error 404 if it comes to areas (usually then the area name is passed in the URL as a query string instead of being inserted before the controller as in ../AreaControllerName?Area=AreaName instead of ../AreaName/AreaControllerName)

So before each controller I now have to include routing like so:

    [Area("MyArea")]
    [Route("MyAreaController/{action}")]
    [Route("MyAreaController/{action}/{id?}")]
    public class MyAreaController: Controller (...)

I even had to start doing that for the top level controllers (as in those not in the areas) otherwise I get the random results mentioned above.

I am going a bit mad here, never faced that problem - this is not a first app I am writing in ASP.NET Core (been working with it since v 1.1) I am absolutely stumped as to what is going on.

Any help or guidance would be greatly appreciated.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,157 questions
0 comments No comments
{count} votes

Accepted answer
  1. Bruce Barker 801 Reputation points
    2021-11-02T18:26:02.48+00:00

    routing matches the first match. as you have no constraint on id, then then area route will only be used if the pattern is:

    a/b/c/d

    you should match area routes first. but no controller should be an area name

              endpoints.MapControllerRoute(
                         name: "areaRoute",
                         pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
              endpoints.MapControllerRoute(
                         name: "default",
                         pattern: "{controller=Home}/{action=Index}/{id?}");
    
    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Pawel Kosinski 21 Reputation points
    2021-11-02T19:41:27.243+00:00

    Hi Bruce

    Thank you for your answer - it actually clears up a lot!
    The only explanation is that earlier on in my projects I was lucky that everything worked the way it did (as in that the patterns and names were unique enough that I never hit that problem)

    Could you elaborate on the constraints if you don't mind? I never used them in this context - I will soon need one pattern where I will have four URI segments (id + 3 other) so I would like to understand better where I was going wrong.

    Cheers!