question

PawelKosinski-4957 avatar image
0 Votes"
PawelKosinski-4957 asked ZhiLv-MSFT commented

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

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.


dotnet-aspnet-core-generaldotnet-aspnet-core-mvc
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

BruceBarker-8516 avatar image
1 Vote"
BruceBarker-8516 answered

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?}");


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

PawelKosinski-4957 avatar image
0 Votes"
PawelKosinski-4957 answered ZhiLv-MSFT commented

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!

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

you could put a constraint on the id such that it could only be an integer, take the case:

{controller=home}/{action=index}/{id?}
{controller=lookup}/{action}/{key}

the second route pattern would never selected, because the first would always be selected, but:


{controller=home}/{action=index}/{id:int?}
{controller=lookup}/{action}/{key}

the pattern a/b/34 would match the first, and a/b/c would match the second. as all there segments are required to pick the second, there is no point in a default controller. of course a better definition would be:

lookup/{action=index}/{key?}
{controller=home}/{action=index}/{id?}





0 Votes 0 ·

Hi @PawelKosinski-4957

You can check the Areas Routing document:

Conventional routing is order-dependent. In general, routes with areas should be placed earlier as they're more specific than routes without an area.

For more detail information about the Route template precedence and endpoint selection order, you can refer the following article:

Route template precedence and endpoint selection order

Attribute route order

0 Votes 0 ·