Razor Pages 404 after updating to ASP.NET Core 7 RC1
See original GitHub issueIs there an existing issue for this?
- I have searched the existing issues
Describe the bug
After updating two internal applications from ASP.NET Core 7 preview 7 to RC1, endpoints related to Razor Pages in the applications started to return HTTP 404 errors when requested via our integration tests that build on WebApplicationFactory<T>
to host the application.
The curiosity of the issue is that is does not happen when running the application build and tests locally on Windows 11 with the CLI or in Visual Studio 2022 17.4 Preview 2, but happens consistently when we run the same CLI script in our CI which currently runs on Windows Server 2016.
Both applications contain a single Razor Page used to serve an HTML page, and otherwise are APIs that contain Minimal API endpoints.
We also updated two further applications to RC1 that had not yet been upgraded from ASP.NET 6 at all. The third was a web application that contains several Razor Pages to power a handful of pages plus some Minimal API endpoints, the fourth is an MVC application that also has some Minimal API endoints.
The third application’s also has the same issue as the first and second, the fourth application works as expected.
Two further applications that use Razor Pages have been successfully updated to RC1 with no issues, which suggests the issue isn’t as simple as something like “Razor Pages is broken”.
The first two applications worked exactly as expected compared to ASP.NET Core 6 when running ASP.NET Core 7 preview 7.
Expected Behavior
The endpoints associated with the Razor Pages endpoints return the appropriate content rather than an HTTP 404 response.
Steps To Reproduce
We have yet to narrow down the issue enough to create a minimal repro project, and as the only apps affected are internal we can’t just add them as-is to a public GitHub repo.
We will update this issue with a repro if we find one with further investigation. At this stage we thought it best to log the issue now in case the description has enough information in it for someone to think of a likely candidate change that may have broken something.
Exceptions (if any)
None.
.NET Version
7.0.100-rc.1.22431.12
Anything else?
We added an endpoint to the application for a branch based on ASP.NET Core 7 preview 7 and RC1 that dumps the endpoint graph of the first application to a unit test to compare them. Other than ordering, the most appropriate piece of information of note is that the endpoint that we get a 404 for (the Razor Page with a URL of /docs
) is missing from the graph in RC1.
app.MapGet("_dev/endpoint-graph", (DfaGraphWriter graphWriter, EndpointDataSource endpointData) =>
{
using var writer = new StringWriter();
graphWriter.Write(endpointData, writer);
string graph = writer.ToString();
return Results.Text(graph);
});
[Fact]
public async Task Get_Endpoint_Graph()
{
// Arrange
using var client = Fixture.CreateDefaultClient();
// Act
using var response = await client.GetAsync("/_dev/endpoint-graph");
// Assert
response.StatusCode.ShouldBe(HttpStatusCode.OK);
Fixture.OutputHelper.WriteLine(await response.Content.ReadAsStringAsync());
true.ShouldBeFalse(); // Force failure to dump the output
}
ASP.NET Core 7 preview 7
digraph DFA {
0 [label="/configuration/debug/ HTTP: GET"]
1 [label="/configuration/debug/ HTTP: *"]
2 -> 0 [label="HTTP: GET"]
2 -> 1 [label="HTTP: *"]
2 [label="/configuration/debug/"]
3 [label="/configuration/updates/ HTTP: POST"]
4 [label="/configuration/updates/ HTTP: *"]
5 -> 3 [label="HTTP: POST"]
5 -> 4 [label="HTTP: *"]
5 [label="/configuration/updates/"]
6 [label="/configuration/toggles/ HTTP: GET"]
7 [label="/configuration/toggles/ HTTP: *"]
8 -> 6 [label="HTTP: GET"]
8 -> 7 [label="HTTP: *"]
8 [label="/configuration/toggles/"]
9 [label="/configuration/test/ HTTP: GET"]
10 [label="/configuration/test/ HTTP: *"]
11 -> 9 [label="HTTP: GET"]
11 -> 10 [label="HTTP: *"]
11 [label="/configuration/test/"]
12 -> 2 [label="/debug"]
12 -> 5 [label="/updates"]
12 -> 8 [label="/toggles"]
12 -> 11 [label="/test"]
12 [label="/configuration/"]
13 [label="/_dev/endpoint-graph/ HTTP: GET"]
14 [label="/_dev/endpoint-graph/ HTTP: *"]
15 -> 13 [label="HTTP: GET"]
15 -> 14 [label="HTTP: *"]
15 [label="/_dev/endpoint-graph/"]
16 -> 15 [label="/endpoint-graph"]
16 [label="/_dev/"]
17 [label="/consumer/me/orders/{...}/{...}/newbasket/ HTTP: POST"]
18 [label="/consumer/me/orders/{...}/{...}/newbasket/ HTTP: *"]
19 -> 17 [label="HTTP: POST"]
19 -> 18 [label="HTTP: *"]
19 [label="/consumer/me/orders/{...}/{...}/newbasket/"]
20 -> 19 [label="/newbasket"]
20 [label="/consumer/me/orders/{...}/{...}/"]
21 -> 20 [label="/*"]
21 [label="/consumer/me/orders/{...}/"]
22 -> 21 [label="/*"]
22 [label="/consumer/me/orders/"]
23 -> 22 [label="/orders"]
23 [label="/consumer/me/"]
24 -> 23 [label="/me"]
24 [label="/consumer/"]
25 [label="/health/validate/ HTTP: GET"]
26 [label="/health/validate/ HTTP: HEAD"]
27 [label="/health/validate/ HTTP: *"]
28 -> 25 [label="HTTP: GET"]
28 -> 26 [label="HTTP: HEAD"]
28 -> 27 [label="HTTP: *"]
28 [label="/health/validate/"]
29 [label="/health/dependencies/ HTTP: GET"]
30 [label="/health/dependencies/ HTTP: HEAD"]
31 [label="/health/dependencies/ HTTP: *"]
32 -> 29 [label="HTTP: GET"]
32 -> 30 [label="HTTP: HEAD"]
32 -> 31 [label="HTTP: *"]
32 [label="/health/dependencies/"]
33 [label="/health/check/ HTTP: GET"]
34 [label="/health/check/ HTTP: HEAD"]
35 [label="/health/check/ HTTP: *"]
36 -> 33 [label="HTTP: GET"]
36 -> 34 [label="HTTP: HEAD"]
36 -> 35 [label="HTTP: *"]
36 [label="/health/check/"]
37 -> 28 [label="/validate"]
37 -> 32 [label="/dependencies"]
37 -> 36 [label="/check"]
37 [label="/health/"]
38 [label="/boom/ HTTP: GET"]
39 [label="/boom/ HTTP: *"]
40 -> 38 [label="HTTP: GET"]
40 -> 39 [label="HTTP: *"]
40 [label="/boom/"]
41 [label="/error/ HTTP: DELETE"]
42 [label="/error/ HTTP: GET"]
43 [label="/error/ HTTP: HEAD"]
44 [label="/error/ HTTP: OPTIONS"]
45 [label="/error/ HTTP: PATCH"]
46 [label="/error/ HTTP: POST"]
47 [label="/error/ HTTP: PUT"]
48 [label="/error/ HTTP: *"]
49 -> 41 [label="HTTP: DELETE"]
49 -> 42 [label="HTTP: GET"]
49 -> 43 [label="HTTP: HEAD"]
49 -> 44 [label="HTTP: OPTIONS"]
49 -> 45 [label="HTTP: PATCH"]
49 -> 46 [label="HTTP: POST"]
49 -> 47 [label="HTTP: PUT"]
49 -> 48 [label="HTTP: *"]
49 [label="/error/"]
50 [label="/swagger-ui/ HTTP: GET"]
51 [label="/swagger-ui/ HTTP: *"]
52 -> 50 [label="HTTP: GET"]
52 -> 51 [label="HTTP: *"]
52 [label="/swagger-ui/"]
53 [label="/swagger/ HTTP: GET"]
54 [label="/swagger/ HTTP: *"]
55 -> 53 [label="HTTP: GET"]
55 -> 54 [label="HTTP: *"]
55 [label="/swagger/"]
56 [label="/version/ HTTP: GET"]
57 [label="/version/ HTTP: *"]
58 -> 56 [label="HTTP: GET"]
58 -> 57 [label="HTTP: *"]
58 [label="/version/"]
59 [label="/docs/"]
60 [label="/metrics/ HTTP: GET"]
61 [label="/metrics/ HTTP: *"]
62 -> 60 [label="HTTP: GET"]
62 -> 61 [label="HTTP: *"]
62 [label="/metrics/"]
63 [label="/ HTTP: GET"]
64 [label="/ HTTP: *"]
65 -> 12 [label="/configuration"]
65 -> 16 [label="/_dev"]
65 -> 24 [label="/consumer"]
65 -> 37 [label="/health"]
65 -> 40 [label="/boom"]
65 -> 49 [label="/error"]
65 -> 52 [label="/swagger-ui"]
65 -> 55 [label="/swagger"]
65 -> 58 [label="/version"]
65 -> 59 [label="/docs"]
65 -> 62 [label="/metrics"]
65 -> 63 [label="HTTP: GET"]
65 -> 64 [label="HTTP: *"]
65 [label="/"]
}
ASP.NET Core 7 RC1
digraph DFA {
0 [label="/configuration/debug/ HTTP: GET"]
1 [label="/configuration/debug/ HTTP: *"]
2 -> 0 [label="HTTP: GET"]
2 -> 1 [label="HTTP: *"]
2 [label="/configuration/debug/"]
3 [label="/configuration/test/ HTTP: GET"]
4 [label="/configuration/test/ HTTP: *"]
5 -> 3 [label="HTTP: GET"]
5 -> 4 [label="HTTP: *"]
5 [label="/configuration/test/"]
6 [label="/configuration/toggles/ HTTP: GET"]
7 [label="/configuration/toggles/ HTTP: *"]
8 -> 6 [label="HTTP: GET"]
8 -> 7 [label="HTTP: *"]
8 [label="/configuration/toggles/"]
9 [label="/configuration/updates/ HTTP: POST"]
10 [label="/configuration/updates/ HTTP: *"]
11 -> 9 [label="HTTP: POST"]
11 -> 10 [label="HTTP: *"]
11 [label="/configuration/updates/"]
12 -> 2 [label="/debug"]
12 -> 5 [label="/test"]
12 -> 8 [label="/toggles"]
12 -> 11 [label="/updates"]
12 [label="/configuration/"]
13 [label="/version/ HTTP: GET"]
14 [label="/version/ HTTP: *"]
15 -> 13 [label="HTTP: GET"]
15 -> 14 [label="HTTP: *"]
15 [label="/version/"]
16 [label="/swagger/ HTTP: GET"]
17 [label="/swagger/ HTTP: *"]
18 -> 16 [label="HTTP: GET"]
18 -> 17 [label="HTTP: *"]
18 [label="/swagger/"]
19 [label="/swagger-ui/ HTTP: GET"]
20 [label="/swagger-ui/ HTTP: *"]
21 -> 19 [label="HTTP: GET"]
21 -> 20 [label="HTTP: *"]
21 [label="/swagger-ui/"]
22 [label="/error/ HTTP: DELETE"]
23 [label="/error/ HTTP: GET"]
24 [label="/error/ HTTP: HEAD"]
25 [label="/error/ HTTP: OPTIONS"]
26 [label="/error/ HTTP: PATCH"]
27 [label="/error/ HTTP: POST"]
28 [label="/error/ HTTP: PUT"]
29 [label="/error/ HTTP: *"]
30 -> 22 [label="HTTP: DELETE"]
30 -> 23 [label="HTTP: GET"]
30 -> 24 [label="HTTP: HEAD"]
30 -> 25 [label="HTTP: OPTIONS"]
30 -> 26 [label="HTTP: PATCH"]
30 -> 27 [label="HTTP: POST"]
30 -> 28 [label="HTTP: PUT"]
30 -> 29 [label="HTTP: *"]
30 [label="/error/"]
31 [label="/boom/ HTTP: GET"]
32 [label="/boom/ HTTP: *"]
33 -> 31 [label="HTTP: GET"]
33 -> 32 [label="HTTP: *"]
33 [label="/boom/"]
34 [label="/health/check/ HTTP: GET"]
35 [label="/health/check/ HTTP: HEAD"]
36 [label="/health/check/ HTTP: *"]
37 -> 34 [label="HTTP: GET"]
37 -> 35 [label="HTTP: HEAD"]
37 -> 36 [label="HTTP: *"]
37 [label="/health/check/"]
38 [label="/health/dependencies/ HTTP: GET"]
39 [label="/health/dependencies/ HTTP: HEAD"]
40 [label="/health/dependencies/ HTTP: *"]
41 -> 38 [label="HTTP: GET"]
41 -> 39 [label="HTTP: HEAD"]
41 -> 40 [label="HTTP: *"]
41 [label="/health/dependencies/"]
42 [label="/health/validate/ HTTP: GET"]
43 [label="/health/validate/ HTTP: HEAD"]
44 [label="/health/validate/ HTTP: *"]
45 -> 42 [label="HTTP: GET"]
45 -> 43 [label="HTTP: HEAD"]
45 -> 44 [label="HTTP: *"]
45 [label="/health/validate/"]
46 -> 37 [label="/check"]
46 -> 41 [label="/dependencies"]
46 -> 45 [label="/validate"]
46 [label="/health/"]
47 [label="/consumer/me/orders/{...}/{...}/newbasket/ HTTP: POST"]
48 [label="/consumer/me/orders/{...}/{...}/newbasket/ HTTP: *"]
49 -> 47 [label="HTTP: POST"]
49 -> 48 [label="HTTP: *"]
49 [label="/consumer/me/orders/{...}/{...}/newbasket/"]
50 -> 49 [label="/newbasket"]
50 [label="/consumer/me/orders/{...}/{...}/"]
51 -> 50 [label="/*"]
51 [label="/consumer/me/orders/{...}/"]
52 -> 51 [label="/*"]
52 [label="/consumer/me/orders/"]
53 -> 52 [label="/orders"]
53 [label="/consumer/me/"]
54 -> 53 [label="/me"]
54 [label="/consumer/"]
55 [label="/metrics/ HTTP: GET"]
56 [label="/metrics/ HTTP: *"]
57 -> 55 [label="HTTP: GET"]
57 -> 56 [label="HTTP: *"]
57 [label="/metrics/"]
58 [label="/_dev/endpoint-graph/ HTTP: GET"]
59 [label="/_dev/endpoint-graph/ HTTP: *"]
60 -> 58 [label="HTTP: GET"]
60 -> 59 [label="HTTP: *"]
60 [label="/_dev/endpoint-graph/"]
61 -> 60 [label="/endpoint-graph"]
61 [label="/_dev/"]
62 [label="/ HTTP: GET"]
63 [label="/ HTTP: *"]
64 -> 12 [label="/configuration"]
64 -> 15 [label="/version"]
64 -> 18 [label="/swagger"]
64 -> 21 [label="/swagger-ui"]
64 -> 30 [label="/error"]
64 -> 33 [label="/boom"]
64 -> 46 [label="/health"]
64 -> 54 [label="/consumer"]
64 -> 57 [label="/metrics"]
64 -> 61 [label="/_dev"]
64 -> 62 [label="HTTP: GET"]
64 -> 63 [label="HTTP: *"]
64 [label="/"]
}
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:6 (6 by maintainers)
Thanks for reporting this and for actually root-causing it, @martincostello 👍 Closing as there is no action pending from our side.
I think the root cause is this bug in the SonarQube scanner for MSBuild which was fixed in version 5.7: https://github.com/SonarSource/sonar-scanner-msbuild/issues/1099