Reputation: 7348
I'm experiencing a strange behavior when launching an ASP.NET core 3.1 web application from Visual Studio 2019 using kestrel (I mean the launching profile which does not use IIS express).
I have created a minimal application to reproduce the issue.
OS: Windows 10 (build 19041.746) Visual Studio version: Visual Studio 2019 version 16.8.4
This is the csproj file:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
</Project>
This is the launchSettings.json file:
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:52222",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"TestWebApplication": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5002",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
This is the Program.cs file:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace TestWebApplication
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
This is the Startup.cs file:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace TestWebApplication
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
When I launch this web application by using the TestWebApplication profile from Visual Studio everything works fine: kestrel is launched at http://localhost:5002 and the web browser is launched at http://localhost:5002/weatherforecast.
This is exactly what I would expect from the provided launchSettings.json
file.
Consider the following change to the Program.cs, made to customize the application configuration sources:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
namespace TestWebApplication
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(builder =>
{
builder.Sources.Clear();
builder.AddEnvironmentVariables();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
This change breaks everything in terms of interaction with the launchSettings.json file. The following happens:
Basically it seems that the file launchSettings.json is ignored and some defaults are used instead.
I have also observed the following:
builder.Sources.Clear();
Is this a bug ? Am I missing anything ?
SOME CLARIFICATIONS
I'm clearing the configuration sources in order to have full control over the configuration sources themselves. Put another way, I would like to remove all the existing configuration sources and start from scratch. According to this documentation this approach seems to be allowed.
Notice that the exact same code works as expected when using the WebHost
class instead of the Host
class. In that case the configuration sources can be fully customized and the ability to read the launchSettings.json
file is maintained for Kestrel too. I'm trying to achieve the same effect with the generic Host
class, which is the recommended class to be used instead of WebHost
in ASP.NET core 3.1
Upvotes: 5
Views: 2747
Reputation: 7348
I have finally managed this issue.
That's not an ASP.NET core 3.1 bug, insted this is the way the generic Host
is designed to work.
Basically the configuration for the port number which is specified inside the lanchSettings.json
file is passed to the ASP.NET core application by means of some environment variables prefixed by ASPNETCORE_
. These environment variables are set automatically by Visual Studio. The one responsible for the kestrel port binding is called ASPNETCORE_URLS
.
When doing builder.Sources.Clear();
the configuration source for the environment variables prefixed by ASPNETCORE_
is cleared away. So, in order to fix the issue, it is necessary to replace this configuration source:
.ConfigureAppConfiguration(builder =>
{
builder.Sources.Clear();
builder.AddEnvironmentVariables();
builder.AddEnvironmentVariables("ASPNETCORE_");
})
All the details are available here
Upvotes: 6