Kestrel Web Server returns 404 to all requests while using inherited Startup from another project (application, assembly). Net Core 3.1.
See original GitHub issueDescription of the bug:
Link to repository with solution: https://github.com/AnastasiyaPoli/MemberService
Short description of the solution: there are two projects in solution: web project MemberService.Api and tests project MemberService.SystemTests. MemberService.Api starts Kestrel service and has a controller DiagnosticController with endpoint “ping”. MemberService.SystemTests has a test to test the first project. It starts Kestrel service, uses a proxy and calls endpoint “ping”.
The problem is: in MemberService.SystemTests I have to use TestStartup (declared in file TestStartup.cs in project MemberService.SystemTests), that inherits Startup from project MemberService.Api, because some of settings should be changed for tests (for example, if I am using Application Insights in my project, I will not use them for tests). Configuring Kestrel server, that uses inherited TestStartup was a big problem.
In file KestrelWebService.cs (line 17) there is such code now for service configuration:
Server = new WebHostBuilder()
.UseKestrel()
.UseStartup<TestStartup>()
.ConfigureKestrel((context, options) =>
{
options.Listen(IPAddress.Loopback, 5000);
})
.UseConfiguration(Configuration)
.UseSetting("applicationName", "MemberService.Api")
.Build();
In this way the test Given_ServiceIsRunning_When_PingActionIsCalled_Then_ResponseStatusCodeShouldBeSucceed in file DiagnosticTests.cs works fine. But the line UseSetting("applicationName", "MemberService.Api")
is a hack to change assembly (application) name after building a server. Without it application name “MemberService.SystemTests” is used and the test fails: “ping” call to server is not 200 (OK), but 404 (NotFound).
Steps to reproduce
- Run test Given_ServiceIsRunning_When_PingActionIsCalled_Then_ResponseStatusCodeShouldBeSucceed in file DiagnosticTests.cs. You will get successful result.
- Comment line
.UseSetting("applicationName", "MemberService.Api")
(line 28) in file KestrelWebService.cs. - Run test Given_ServiceIsRunning_When_PingActionIsCalled_Then_ResponseStatusCodeShouldBeSucceed in file DiagnosticTests.cs again. You will get failure result. “Ping” request to server will return 404 (NotFound). You can see it, setting a breakpoint on line
return Result.ParseFromHttpResponse(response);
(line 12) in file HttpClientExtensions.cs and look at response variable.
Test is also successful in such case:
- Comment line
.UseSetting("applicationName", "MemberService.Api")
(line 28) in file KestrelWebService.cs. - In file KestrelWebService.cs in line
.UseStartup<TestStartup>()
(line 22) change type from TestStartup to TestStartupApi (declared in file Startup.cs in project MemberService.Api). - Run test Given_ServiceIsRunning_When_PingActionIsCalled_Then_ResponseStatusCodeShouldBeSucceed in file DiagnosticTests.cs. You will get successful result.
Resolution: classes TestStartupApi and TestStartup are completely the same, but located in different projects (applications, assemblies). With TestStartupApi Kestrel service works fine (“ping” call is successful) but with TestStartup - it is not working (“ping” call is failing). Changing assembly (application) name from “MemberService.SystemTests” to “MemberService.Api” after building a server helps, but it does not seem like normal behavior.
Important note: the code worked for .NET Core 2.2, but caused problems for .NET Core 3.1. The issue became visible after changing the version.
Could you suggest a correct solution to configure Kestrel service for project MemberService.SystemTests in this case? Or is it a bug that is going to be fixed? Thanks in advance!
Exceptions:
The problem is not followed by any exceptions.
Further technical details
- ASP.NET Core version: 3.1
- the output of
dotnet --info
:
.NET Core SDK (reflecting any global.json):
Version: 3.1.202
Commit: 6ea70c8dca
Runtime Environment:
OS Name: Windows
OS Version: 10.0.17134
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.1.202\
Host (useful for support):
Version: 3.1.4
Commit: 0c2e69caa6
.NET Core SDKs installed:
2.1.200 [C:\Program Files\dotnet\sdk]
2.1.400 [C:\Program Files\dotnet\sdk]
2.1.402 [C:\Program Files\dotnet\sdk]
2.1.403 [C:\Program Files\dotnet\sdk]
2.1.514 [C:\Program Files\dotnet\sdk]
2.1.602 [C:\Program Files\dotnet\sdk]
2.2.203 [C:\Program Files\dotnet\sdk]
3.1.202 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
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.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.18 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.4 [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.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
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.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.18 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.4 [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.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.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.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.18 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.4 [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.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET Core runtimes or SDKs: https://aka.ms/dotnet-download
- The IDE: Visual Studio Professional 2019, version: 16.5.5
Issue Analytics
- State:
- Created 3 years ago
- Comments:19 (9 by maintainers)
@davidfowl thanks for the solution and explanations. It really works if
<EnableDefaultContentItems>false</EnableDefaultContentItems>
added to .csproj file (at least, in my case).Checked once again the documentation https://docs.microsoft.com/en-us/dotnet/core/compatibility/2.2-3.1 and did not find information about that change. It would be just great if it could be added, because the behavior is not obvious at all when the error occurs.
@AnastasiyaPoli I’ll take a look at your repos today.