Async routes stopped working in ASP.NET Core 3

Av Peter Örneholm | Blogg | 27 september 2019

I’m part of the team that maintains Active Login, an ASP.NET authentication provider for Swedish BankID. The package is targeting .NET Standard 2.0 and should therefore need to updates for ASP.NET Core 3, but we have samples of usages written in ASP.NET Core 2.2, so I set out to update them. The PR to go from 2.2 to 3.0 can be found here, if interesting for anyone.

While doing the upgrade I realized the package didn’t work properly. Some debugging and I found out that the wrong URL was resolved for my API actions.

TL;DR: In ASP.NET Core 3, if you have Action methods suffixed with Async but a route path that does not include Async, refer to them without the Async suffix when resolving a URL through (for example) Url.Action(). This seems to be a breaking change from ASP.NET Core 2.2 which is not officially documented.

So, change Url.Action(”ActionAsync”, “Controller”) into Url.Action(”Action”, “Controller”) when upgrading from Core 2.2 to Core 3.0.

Some more in depth:

After some googling, I found this GitHub Issue, and it seems to be considered a minor change and that’s why I didn’t see this as part of the official documentation. I might have used the routing in a way not many people do, but thought it’s worth writing this post for those who have the same issue as me.

Id did create a repo with a minimal setup to verify the behavior. It seems that when running ASP.NET Core 3, you should refer to the action without the Async suffix to get a correct url from Url.Action (or IUrlHelper).

ASP.NET Core 2.2


ASP.NET Core 3.0


Another change is that if the action can’t be found, it will fall back to the url pattern convention. In 2.2 and below it returned an empty string. My guess is that this is related to the new endpoint routing.

So, I hopefully this can save someone a few hours of debugging… :)

Till inlägget