ASP.NET core 3.1:ConfigureAppConfiguration 是否与 launchSettings.json 交互?

Enr*_*one 5 c# .net-core kestrel-http-server asp.net-core asp.net-core-3.1

使用 kestrel 从 Visual Studio 2019 启动 ASP.NET core 3.1 Web 应用程序时,我遇到了奇怪的行为(我的意思是不使用IIS Express 的启动配置文件)。

我创建了一个最小的应用程序来重现该问题。

操作系统:Windows 10(内部版本 19041.746) Visual Studio 版本:Visual Studio 2019 版本 16.8.4

这是 csproj 文件:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>


</Project>
Run Code Online (Sandbox Code Playgroud)

这是 launchSettings.json 文件:

{
  "$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"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这是 Program.cs 文件:

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>();
            });
  }
}
Run Code Online (Sandbox Code Playgroud)

这是 Startup.cs 文件:

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();
      });
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

当我使用Visual Studio 中的TestWebApplication配置文件启动此 Web 应用程序时,一切正常:kestrel 在http://localhost:5002启动,Web 浏览器在http://localhost:5002/weatherforecast启动。

这正是我对所提供的文件的期望launchSettings.json

考虑对 Program.cs 进行以下更改,以自定义应用程序配置源:

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>();
            });
  }
}
Run Code Online (Sandbox Code Playgroud)

此更改破坏了与launchSettings.json文件交互方面的所有内容。发生以下情况:

  • kester 在http://localhost:5000https://localhost:5001上启动
  • Web 浏览器未在http://localhost:5002/weatherforecast上启动

基本上,似乎文件launchSettings.json被忽略,并使用一些默认值。

我还观察到以下几点:

  • 根本原因似乎是清除配置源的行:builder.Sources.Clear();
  • IIS Express 配置文件不受此问题的影响:即使使用修改后的 Program.cs 文件,它也能按预期工作

这是一个错误吗?我错过了什么吗?

一些澄清

我正在清除配置源,以便完全控制配置源本身。换句话说,我想删除所有现有的配置源并从头开始。根据此文档,这种方法似乎是允许的。

WebHost请注意,当使用类而不是类时,完全相同的代码会按预期工作HostlaunchSettings.json在这种情况下,配置源可以完全自定义,并且Kestrel 也可以保留读取文件的能力。我正在尝试使用泛型类实现相同的效果Host,这是推荐使用的类,而不是WebHost在 ASP.NET core 3.1 中使用

Enr*_*one 6

我终于解决了这个问题。

Host这不是 ASP.NET core 3.1 的错误,而是泛型设计的工作方式。

基本上,文件内指定的端口号配置lanchSettings.json通过一些前缀为 的环境变量传递到 ASP.NET Core 应用程序ASPNETCORE_。这些环境变量由 Visual Studio 自动设置。负责 kestrel 端口绑定的称为ASPNETCORE_URLS

在进行 builder.Sources.Clear();配置时,以 为前缀的环境变量的源ASPNETCORE_将被清除。因此,为了解决该问题,有必要替换此配置源:

.ConfigureAppConfiguration(builder =>
            {
              builder.Sources.Clear();
              builder.AddEnvironmentVariables();
              builder.AddEnvironmentVariables("ASPNETCORE_");
            })
Run Code Online (Sandbox Code Playgroud)

所有详细信息都可以在这里找到