Apparently the order in which you call UseStatusCodePagesWithReExecute and UseRouting matters. I discovered this while trying to debug why status code pages for my app didn't work.
Also, it seems the order of UseStatusCodePages and/or UseStatusCodePagesWithRedirects and UseRouting does not matter.
This is somewhat strange/inconsistent behaviour, I believe it is a bug.
It shouldn't be required to have the exact correct order or at least this should be documented (it is not at the time of reporting this bug).
Having it like this doesn't work for UseStatusCodePagesWithReExecute
app.UseRouting();
app.UseStatusCodePagesWithReExecute("/status-code/{0}");
However having the other two in the same order does work (for what they're supposed to do):
app.UseRouting();
app.UseStatusCodePagesWithRedirects("~/status-code/{0}");
app.UseStatusCodePages();
Having it this way for UseStatusCodePagesWithReExecute does make this feature to work
app.UseStatusCodePagesWithReExecute("/status-code/{0}");
app.UseRouting();
I've documented how I got at this here https://github.com/dotnet/AspNetCore.Docs/issues/19364
.NET Core SDK (reflecting any global.json):
Version: 3.1.301
Commit: 7feb845744
Runtime Environment:
OS Name: Windows
OS Version: 10.0.18363
OS Platform: Windows
RID: win10-x64
Base Path: C:Program Filesdotnetsdk3.1.301
Host (useful for support):
Version: 3.1.5
Commit: 65cd789777
.NET Core SDKs installed:
3.1.101 [C:Program Filesdotnetsdk]
3.1.202 [C:Program Filesdotnetsdk]
3.1.301 [C:Program Filesdotnetsdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.19 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.8 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.19 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.8 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.1 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.4 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.5 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.19 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 2.2.8 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 3.1.1 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 3.1.4 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 3.1.5 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.1 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.4 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.5 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
To install additional .NET Core runtimes or SDKs:
https://aka.ms/dotnet-download
What handles the path /status-code/{0} in your app, a controller? That's why it needs to run routing after changing the path.
A controller, of course. Even though I can now understand how such order makes sense it is somewhat unintuitive - and requires more effort/thinking on developers part to get it right.
Update: Not to mention I only now know why is it so after numerous hours of troubleshooting.
Here's the associated doc. I'll transfer this issue to the docs repo to clarify it.
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-3.1#usestatuscodepageswithreexecute
- "If you point to an endpoint within the app, create an MVC view or Razor page for the endpoint."
+ "If you point to an endpoint within the app, create an MVC view or Razor page for the endpoint. Ensure UseStatusCodePagesWithReExecute is placed before UseRouting so the request can be rerouted to the status page."
@Rick-Anderson Shall I take care of this now whilst I've got everything open?
@Rick-Anderson Shall I take care of this now whilst I've got everything open?
Yes, that would be great!
Thanks for updating the docs.
But don't you think that order change requirement for one out of three related method calls makes little/no sense? Feels wrong to me and makes me wonder what else can one broke when changing the order of middleware calls. Now I understand some order is required but for semantically related methods it shouldn't matter.
All three versions have the requirement that they be placed earlier in the pipeline than the component that sets the status code. And yes the ReExecute variant does add the constraint that it be placed before routing so that it can re-route requests. The others don't have this constraint because they handle the response internally, but you could put them all before UseRouting for consistency. Let me know if you find any docs or samples recommending otherwise.
Yes, pipeline ordering can be error prone. However, given we have a pipeline model, it's not possible to implement the ReExecute functionality without this ordering constraint with UseRouting. The only fix I see for the confusion here would be to remove the ReExecute functionality.
@Tratcher if you'd like to see less of these every week upvote https://github.com/dotnet/aspnetcore/issues/18791
@Tratcher Definitely don鈥檛 remove ReExecute, we need it (now that鈥檚 working) ;)