Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom controller route with async action no longer working after upgrade from 2.2 to 3.0-RC1 #14103

Open
nphmuller opened this issue Sep 18, 2019 · 10 comments
Labels
affected-very-few This issue impacts very few customers area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-routing severity-nice-to-have This label is used by an internal tool
Milestone

Comments

@nphmuller
Copy link

nphmuller commented Sep 18, 2019

Describe the bug

The 2.2 -> 3.0 migration guide status that MVC controllers can be migrated by replacing MapRoute with MapControllerRoute.

This doesn't work for the following case:

Say I have the following controller in my project root:

public class CustomEndpoints : ControllerBase
{
    [HttpGet]
    public Task<string> HiAsync()
    {
        return Task.FromResult("Hi!");
    }
}

in ASP.NET Core 2.2 my routing configuration looks like this:

app.UseMvc(routes =>
{
    routes.MapRoute("test_route", "test/hi",
        new
        {
            Controller = nameof(CustomEndpoints),
            Action = nameof(CustomEndpoints.HiAsync)
        }
    );
});

When visiting http://localhost:5000/test/hi, I'm greeted by a friendly Hi! message.

After upgrading to ASP.NET Core 3.0-RC1 the routing config looks like this:

app.UseRouting();
app.UseEndpoints(routes =>
{
    routes.MapControllerRoute("test_route", "test/hi",
        new
        {
            Controller = nameof(CustomEndpoints),
            Action = nameof(CustomEndpoints.HiAsync)
        }
    );
});

When visiting http://localhost:5000/test/hi, I'm now only greeted by a 404 response.

Additionally, everything seems to work in 3.0-RC1 when the action (HiAsync) doesn't carry the Async postfix (is named Hi). The return type doesn't matter.

Full a full repro see:
ASP.NET Core 2.2
ASP.NET Core 3.0-RC1

Additional context

Add any other context about the problem here.
Include the output of dotnet --info

dotnet --info

.NET Core SDK (reflecting any global.json): Version: 3.0.100-rc1-014190 Commit: c4d43f672d

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18362
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100-rc1-014190\

Host (useful for support):
Version: 3.0.0-rc1-19456-20
Commit: 8f5d7b1ba4

.NET Core SDKs installed:
2.1.402 [C:\Program Files\dotnet\sdk]
2.1.403 [C:\Program Files\dotnet\sdk]
2.1.500 [C:\Program Files\dotnet\sdk]
2.1.502 [C:\Program Files\dotnet\sdk]
2.1.503 [C:\Program Files\dotnet\sdk]
2.1.504 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
2.1.507 [C:\Program Files\dotnet\sdk]
2.1.508 [C:\Program Files\dotnet\sdk]
2.1.600 [C:\Program Files\dotnet\sdk]
2.1.601 [C:\Program Files\dotnet\sdk]
2.1.602 [C:\Program Files\dotnet\sdk]
2.1.604 [C:\Program Files\dotnet\sdk]
2.1.700 [C:\Program Files\dotnet\sdk]
2.1.701 [C:\Program Files\dotnet\sdk]
2.1.800-preview-009696 [C:\Program Files\dotnet\sdk]
2.1.801 [C:\Program Files\dotnet\sdk]
2.1.802 [C:\Program Files\dotnet\sdk]
2.2.100 [C:\Program Files\dotnet\sdk]
2.2.102 [C:\Program Files\dotnet\sdk]
2.2.104 [C:\Program Files\dotnet\sdk]
2.2.202 [C:\Program Files\dotnet\sdk]
2.2.204 [C:\Program Files\dotnet\sdk]
2.2.300 [C:\Program Files\dotnet\sdk]
2.2.301 [C:\Program Files\dotnet\sdk]
2.2.401 [C:\Program Files\dotnet\sdk]
2.2.402 [C:\Program Files\dotnet\sdk]
3.0.100-preview8-013656 [C:\Program Files\dotnet\sdk]
3.0.100-rc1-014190 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-preview8.19405.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-rc1.19457.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview8-28405-07 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-rc1-19456-20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0-preview8-28405-07 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.0.0-rc1-19456-20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

@nphmuller nphmuller changed the title Custom controller route with async action no longer working after upgrade from 2.2 to 3.0-RC2 Custom controller route with async action no longer working after upgrade from 2.2 to 3.0-RC1 Sep 18, 2019
@khellang
Copy link
Member

Additionally, everything seems to work in 3.0-RC1 when the action (HiAsync) doesn't carry the Async postfix (is named Hi). The return type doesn't matter.

Yeah, this is an announced breaking change.

@khellang
Copy link
Member

As mentioned in #8998 (comment), ideally the MapControllerRoute would also apply the same logic and strip the Async suffix so you could continue to use nameof(CustomEndpoints.HiAsync).

@nphmuller
Copy link
Author

Thanks! I'll open an issue at the docs to maybe add this to the migration docs.
Can I leave this issue open as a feature request for MapControllerRoute?

@pranavkm pranavkm added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Sep 18, 2019
@mkArtakMSFT mkArtakMSFT added the enhancement This issue represents an ask for new feature or an enhancement to an existing one label Sep 18, 2019
@mkArtakMSFT mkArtakMSFT added this to the 5.0.0-preview1 milestone Sep 18, 2019
@mkArtakMSFT
Copy link
Member

Thanks for contacting us, @nphmuller.
We'll also think about about this during 5.0 timeframe and see whether we can come up with something good.

@mkArtakMSFT
Copy link
Member

We've moved this issue to the Backlog milestone. This means that it is not going to happen for the coming release. We will reassess the backlog following the current release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.

@rubo
Copy link

rubo commented May 21, 2020

This means that it is not going to happen for the coming release.

@mkArtakMSFT By coming release, do you mean the next preview release or the final one in this fall?

@DavidBridge
Copy link

I am going to assume that my issue is related.
If I have a controller with
[Route("[controller]/[action]")]
public async Task XXXAsync()

then my calls fail, but if I change the route definition to
[Route("[Controller]/XXXAsync")]
then it works fine.

@robertsynoradzki
Copy link

Is there any update on this, so that I can stop writing

Url.ActionLink(nameof(CallbackAsync).TrimEnd("Async"), nameof(AuthenticationController).TrimEnd("Controller"))

? :)

@khellang
Copy link
Member

khellang commented Dec 9, 2020

Just remove the Async suffix from your action methods 👼🏻 :trollface:

@javiercn javiercn added affected-very-few This issue impacts very few customers severity-nice-to-have This label is used by an internal tool labels Feb 19, 2021 — with ASP.NET Core Issue Ranking
@benmccallum
Copy link
Contributor

benmccallum commented Sep 30, 2021

Just remove the Async suffix from your action methods 👼🏻 :trollface:

If we didn't have to manually opt-out Controller classes from conventions that the rest of our codebase follows this would be ok.
VSTHRD200 // Use "Async" suffix for async methods

I'm migrating from MVC5 and Web API 2. In MVC we were avoiding Async suffixes for nicer urls, but in the API we weren't as usually they had explicit route templates.

Now, since they're merged into just "MVC", I'm left wondering what the best path fwd is.

I doubt this only affected very few, I bet it affected everyone who was doing nameof, and they've had to work around it. IMO, the ball was dropped a little here; this would've been fine if the url generator was also updated to fall in line.

I guess I'll just turn this new default behaviour off. One of those changes that's too painful to adopt on a legacy project. It's a shame as I hate doing #pragma warning disable VSTHRD200 all over the place and was looking forward to this change when I first heard about it.

services.AddMvc(options => options.SuppressAsyncSuffixInActionNames = false);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affected-very-few This issue impacts very few customers area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-routing severity-nice-to-have This label is used by an internal tool
Projects
None yet
Development

No branches or pull requests

9 participants