【发布时间】:2021-05-13 11:04:36
【问题描述】:
我在使用 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>
这是 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"
}
}
}
}
这是 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>();
});
}
}
这是 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();
});
}
}
}
当我使用 Visual Studio 中的 TestWebApplication 配置文件启动此 Web 应用程序时,一切正常:红隼在 http://localhost:5002 并在 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>();
});
}
}
此更改破坏了与 launchSettings.json 文件交互方面的所有内容。会发生以下情况:
- kester 在 http://localhost:5000 和 https://localhost:5001 上启动
- 网络浏览器未在 http://localhost:5002/weatherforecast 上启动
基本上,文件 launchSettings.json 似乎被忽略了,而是使用了一些默认值。
我还观察到以下情况:
- 根本原因似乎是清除配置源的行:
builder.Sources.Clear(); - IIS express 配置文件不受此问题影响:即使使用修改后的 Program.cs 文件,它也能按预期工作
这是一个错误吗?我错过了什么吗?
一些澄清
我正在清除配置源以便完全控制配置源本身。换句话说,我想删除所有现有的配置源并从头开始。根据this documentation,这种方法似乎是允许的。
请注意,当使用 WebHost 类而不是 Host 类时,完全相同的代码会按预期工作。在这种情况下,可以完全自定义配置源,并且 Kestrel 也可以读取launchSettings.json 文件。我正在尝试使用通用的 Host 类来达到相同的效果,这是在 ASP.NET core 3.1 中推荐使用的类而不是 WebHost
【问题讨论】:
-
当您清除配置源时,您已经删除了告诉 Kestrel 绑定到端口 5002 的任何内容。这不会影响使用 IIS Express,因为您的应用程序本身没有侦听端口 5002,IIS 是并将请求反向代理到 Kestrel 内部使用的任何内容。
-
@Valuator 我这样做是因为我想完全自定义配置源。这个想法是删除所有现有的资源并从头开始。根据this docs支持清源。
-
@Valuator 相同的代码与 ASP.NET core 2.2 和
WebHost完美配合。在这种情况下,清除配置源不会破坏读取launchSettings.json的能力,并且还为红隼维护5002端口。你知道如何使用 ASP.NET core 3.1 和通用的Host类来达到同样的效果吗? -
@Valuator 当使用
WebHost而不是Host时,这个完全相同的代码也适用于 ASP.NET core 3.1。这个问题似乎只有在使用通用Host类时才会出现。 -
@Valuator 只是一点旁注。从 ASP.NET core 3.0 开始,IIS 下的默认托管模型是所谓的进程内托管模型。见this documentation。所以我猜想 IIS express 实际上并没有充当 kestrel 的反向代理。
标签: c# asp.net-core .net-core asp.net-core-3.1 kestrel-http-server