如果在.NET8中没有额外的配置,ASP.NET Core App监听的URL为http://localhost:5000
,在这篇文章中我将展示8种方式来改变这个URL,这是我3年前写的一个帖子ASP.NET Core App设置URLs的5种方法(https://andrewlock.net/5-ways-to-set-the-urls-for-an-aspnetcore-app/
),这篇文章将覆盖更多种方法。
ASP.NET Core App设置的URL绑定到启动项有多种方式,我有一个老的帖子针对ASP.NET Core 1.0(https://andrewlock.net/configuring-urls-with-kestrel-iis-and-iis-express-with-asp-net-core/
),前面的帖子是针对.NET Core 3.x,在ASP.NET Core 8中也类似:
UseUrls()
调用WebApplicationBuilder.WebHost.UseUrls()
设置URLs
WebApplication.Urls
使用WebApplication.Urls
直接添加URLs环境变量设置 使用
DOTNET_URLS
和ASPNETCORE_URLS
环境变量设置URLs环境变量设置
port
使用DOTNET_HTTP_PORTS
和ASPNETCORE_HTTP_PORTS
环境变量设置端口(HTTPS
相同的方式)命令行参数方式 在命令行窗口使用
--urls
设置URLsappSettings.json
-使用urls
属性设置URLslaunchSettings.json
使用applicationUrl
属性设置URLs
KestrelServerOptions.Listen()
—在代码中使用Listen()
方法手动配置KestrelServer
地址或者在IConfiguration
使用Kestrel
属性
URLs的格式
在这篇文章中我描述你能绑定的URLs, 但是你不能使用任意的URL,有三个类型的URLs格式你能使用:
IPv4和IPv6回环地址 (eg:
http://localhost:5000
,http://127.0.0.1:5000
, 或者http://[::1]:5000
),格式为{scheme}://{loopbackAddress}:{port}
特定的IP地址(e.g:
http://192.168.8.31:5005
), 格式为:{scheme}://{IPAddress}:{port}
"任意"IP地址格式(e.g.
http://*:6264
),格式为:{scheme}://*:{port}
在上面port也是可选的-如果你省略它,会根据使用的scheme使用默认的端口替换(http
端口80
,https
端口443
)
选择哪种模式依赖于你应用程序的部署模式,例如,你在裸机上部署一个应用程序,你需要明确指定一个IP地址,如果你把你的应用程序部署到容器里,你可以指定"任何"IP地址
注意针对"任意"IP 地址格式 - 你不需要使用* ,你只需要使用不是回环地址(如 localhost
)。这意味着你可以使用 http://,http://+,http://mydomain,或 http://example.org
。所有这些对于配置 Kestrel 都表现相同,并且允许监听任何IP地址。请注意,出于安全原因,你应该确保配置主机过滤。
一旦你知道你监听的URLs
,你需要告诉你的应用程序,在这篇文章中我将展示8种方式:
1. UseUrls()
设置绑定URLs的第一种方式也是最简单的方法,配置WebApplicationBuilder
使用UseUrls()硬编码他们,UseUrls()方法是一个扩展方法,可以在WebHost属性上使用:
var builder = WebApplication.CreateBuilder(args);
// Configure the URLs 👇
builder.WebHost.UseUrls("http://localhost:5003", "https://localhost:5004");
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
UseUrls()方法自 ASP.NET Core 1.0 版本就存在了,从 .NET 6 开始,有一种新的方式,直接使用 WebApplication。
2. WebApplication.Urls和WebApplication.Run()
WebApplication暴露了一个Urls属性针对应用程序配置监听的URLs:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Urls.Add("http://*:5003"); // 👈 Add the URL
app.Run();
背后的逻辑,Urls属性暴露IServerAddressFeature.Addresses集合,因此你也能直接添加地址:
public ICollection<string> Urls => ServerFeatures.GetRequiredFeature<IServerAddressesFeature>().Addresses;
相同的方式,调用app.Run()关联方式设置的URL,你在这里设置的URL在应用程序启动之前被添加到IServerAddressesFeature
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run("http://*:5003"); // 👈 Use the provided URL when running the application
硬编码URLs从来不是一种特别干净和可扩展的解决方案,通常情况下你不要使用这种方法,比较幸运,你可以从配置文件加载URLs,环境变量,命令行参数
3.环境变量
ASP.NET Core提供了高级,可扩展的配置系统能够从多个配置源中加载值,默认情况下,.NET8使用ConfigurationManager从下面位置加载值:
1. appsettings.json 文件
2. 环境变量json文件,例如:appsettings.ENVIRONMENT.json
3. User Secrets
4. 环境变量
5. 命令行参数
你能添加额外的provider从别的位置加载,但是这些都是默认被添加的。你能使用这个系统加载配置并且自定义你的应用程序,但是ASP.NET Core在内部也是用它做配置
ASP.NET Core把下面所有的添加到配置系统:
1. 所有的环境变量被直接添加到配置系统
2. 具有前缀 DOTNET_ 的环境变量,其前缀将被移除并添加到集合中。
3. ASP.NET Core 应用程序,具有前缀 ASPNETCORE_ 的环境变量,其前缀将被移除并添加到集合中。如果你正在创建基于泛型主机的工作服务(使用 HostApplicationBuilder),这些环境变量不会被添加
如果你没有手动使用UseUrls()方法进行覆盖,那么 ASP.NET Core 将使用配置系统中URLS键对应的值。根据上述描述,你可以使用以下任何环境变量来设置URLS(大小写不敏感)
URLS
ASPNETCORE_URLS
DOTNET_URLS
上面的顺序也描述了如果你设置了所有这些环境变量的优先级顺序,URLS 具有最高的优先级
你可以设置你的环境变量通常基于你自己的环境。例如,
1. 命令行 setx ASPNETCORE_URLS "http://localhost:5001"
2. PowerShell $Env:ASPNETCORE_URLS="http://localhost:5001"
3. bash:
export ASPNETCORE_URLS="http://localhost:5001;https://localhost:5002"
正如你在上面看到的,你还可以通过;来传递多个地址进行监听(使用 HTTP 或 HTTPS )
4. 环境变量ports
ASPNETCORE_URLS 和类似的环境变量可用于使用本文开头显示的格式设置 URL,例如:
ASPNETCORE_URLS="http://localhost:5001"—在回环地址(localhost 地址)上监听端口5001。
ASPNETCORE_URLS="http://192.168.8.31:5001"—在指定的 IP 地址上监听端口5001。
ASPNETCORE_URLS="http://*:5001"—在任意IP 地址上监听端口 5001。
有一件事情让我有些困扰,那就是这个变量的名称。对我来说,它暗示着你可以使用像http://example.com:5000这样的地址,你的应用程序将会监听该 DNS 名称。但事实并非如此。上面的 URL 被处理的方式与 http://*:5000 完全相同,它配置了应用程序在任何 IP 地址上监听端口5000
.NET8 添加了新的配置键能够明确的指明这个,使用HTTP_PORTS和HTTPS_PORTS替换指定的URLs并且它可是被使用绑定任何IP地址,你可以使用;指定多个端口,例如
如果你设置下面环境变量:
ASPNETCORE_HTTP_PORTS=5001;5002
ASPNETCORE_HTTPS_PORTS=5003
这些可以扩展到下面的URLs:
http://*:5001
http://*:5002
https://*:5003
就像其他配置键一样,你可以使用 ASPNETCORE_、DOTNET_ 或者不带前缀来指定值:
HTTP_PORTS(或 HTTPS_PORTS)
ASPNETCORE_HTTP_PORTS(或ASPNETCORE_HTTPS_PORTS)
DOTNET_HTTP_PORTS(或 DOTNET_HTTPS_PORTS)
请注意,如果你指定上面的任何一个和 ASPNETCORE_URLS(例如),那么 ASPNETCORE_URLS 的值将优先,并且会在输出中记录一个警告。
warn: Microsoft.AspNetCore.Hosting.Diagnostics[15]
Overriding HTTP_PORTS '5002' and HTTPS_PORTS ''. Binding to values defined by URLS instead 'http://*:5003'.
.NET 8默认Docker 镜像中 ASPNETCORE_HTTP_PORTS 变量默认设置为8080(以前版本的 Docker 镜像中设置了 ASPNETCORE_URLS)。你可以通过设置 ASPNETCORE_HTTP_PORTS 或 ASPNETCORE_URLS(等其他方式)来覆盖这个默认值。
环境变量仅仅是一种添加值到配置的一种方式,命令行参数是另外一种方式
5. 命令行参数
另一种向 ASP.NET Core 的配置系统添加值的方法是使用命令行。如果设置了命令行参数,命令行参数将覆盖环境变量的值。只需在运行应用程序时将 "无前缀" 环境变量作为参数传递,并以 -- 作为前缀。例如:dotnet run -- --urls "http://localhost:5100"
相同的方式,你可以通过使用分号来分隔多个要监听的 URL:dotnet run -- --urls "http://*:5100;http://localhost:5101"
这种方式也适用于dotnet运行时版本,其中你将编译后的 DLL 的路径传递给 dotnet,而不是使用 dotnet run:
dotnet ./WebApplication1.dll --urls "http://*:5100;http://localhost:5101"
你也能使用 --http_ports 和 --https_ports:
dotnet run -- --http_ports "5100;5101" --https_ports "5003;5004"
请注意,dotnet run 命令中额外的 -- 不是打字错误它确保参数被解释为配置的参数,而不是作为 run 命令本身的参数
环境变量和命令行参数使用相同的方式将值添加到ASP.NET Core的配置,你可以使用别的provider将值添加到配置,最常使用的方式appsettings.json文件。
6.appsettings.json
几乎所有现代 .NET 应用程序模板都包含appsettings.json和特定环境的appsettings.Development.json文件,它们向ASP.NET Core 配置系统添加值提供了一种简单的方式。
希望这不会让你感到意外,你可以使用这些文件来使用相同的urls、http_ports 和 https_ports 键来指定应用程序监听的地址。以下是将urls键添加到默认模板的示例:
{
"urls": "http://*:5003", // 👈 Specify the URL
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
这个版本添加http_ports和https_ports键:
{
"http_ports": "5001;5002", // 👈 Expands to http://*:5001 and http://*:5002
"https_ports": "5003", // 👈 Expands to http2://*:5003
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
如果你想在开发和生产环境中使用不同的端口,生产环境中使用appsettings.json,开发环境使用appsettings.Development.json 文件。或者你可以使用适合你的任何模式。
你也可以依赖于另一个 JSON 文件,即launchSettings.json
7. launchSettings.json
除了appsettings.json文件之外,大多数 .NET 项目模板还在 Properties 文件夹中包含一个 launchSettings.json 文件。这个文件不会直接添加到你的配置中;相反,它包含了在开发环境中使用 dotnet run 启动你的 ASP.NET Core 应用程序的各种配置文件。
这个文件通常包含一个或多个从命令行直接启动的配置文件定义,以及一个使用 IIS Express 启动配置文件的定义。这个文件驱动了 Visual Studio 中的Debug下拉菜单。
launchSettings.json提供了一种通过applicationUrl属性轻松设置应用程序地址的方式 - 你可以在iisSettings下看到一个,在每个 HTTP和HTTPS配置文件下也可以看到一个:
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:49412", // 👈 URL to use with IIS Express profile
"sslPort": 44381
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5005", //👈 HTTP only profile
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7045;http://localhost:5005", //👈 HTTP &HTTPS profile
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
当你使用dotnet run命令从命令行运行你的应用程序时,你的应用程序将使用Project命令中的applicationUrl属性:
比如上面 http 配置文件中的http://localhost:5005。
当你使用 IISExpress命令运行应用程序时,你的应用程序将使用来自iisSettings.iisExpress节点的applicationUrl比如 http://localhost:49412。
这个文件是在本地开发时配置环境的最简单方式。事实上,你必须费点事才能不使用 launchSettings.json:
dotnet run --no-launch-profile
这将跳过 launchSettings.json 文件,并回退到使用配置来确定URLs。
到目前为止展示的所有方法都是间接地设置Kestrel的URLs,但你也可以直接设置它们。
8. KestrelServerOptions.Listen()
在大多数 ASP.NET Core 应用程序中默认情况下会配置 Kestrel。如果你愿意的话,你可以手动配置Kestrel的端点,或者使用 IConfiguration 系统来配置 KestrelServerOptions,而不是使用 ASPNETCORE_URLS等提供的更高级别的配置。
默认情况下,当你自托管应用程序或在 IIS out-of process中运行时,会使用 Kestrel。
当你在进程内运行时,将使用IIS HTTP服务器。在Windows上,你还可以使用 HTTP.sys 内核驱动程序
你最有可能需要使用Kestrel的Listen()函数来配置HTTPS证书、SSL/TLS 协议和密码套件,以及服务器名称指示 (SNI) 配置。有很多配置选项可用,所以我建议大部分情况下参考文档。举个例子,你可以像这样使用KestrelServerOptions暴露的Listen()函数:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(opts =>
{
opts.Listen(IPAddress.Loopback, port: 5002); //listen on http://localhost:5002
opts.ListenAnyIP(5003); //listen on http://*:5003
opts.ListenLocalhost(5004, listenOptions => listenOptions.UseHttps()); //listen onhttps://localhost:5004
opts.ListenAnyIP(5005, listenOptions => //listen on https://*:5005
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
这个配置设置了 Kestrel 监听多个地址。当你以这种方式设置 Kestrel 的 URLs 时,它会覆盖通过其他机制设置的 URLS 配置值,比如通过环境变量设置。如果发生这种情况,你会在日志中看到一个警告:
warn: Microsoft.AspNetCore.Server.Kestrel[0]
Overriding address(es) 'http://localhost:5165'. Binding to endpoints defined via IConfiguration and/or UseKestrel() instead.
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://127.0.0.1:5002
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://[::]:5003
info: Microsoft.Hosting.Lifetime[14]
Now listening on: https://localhost:5004
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://[::]:5005
上面的示例中,Kestrel 配置是硬编码的,但并不一定要这样——你可以使用IConfiguration 进行绑定,类似于你可以绑定到urls或 http_ports。上面的 Kestrel 配置也可以在 appsettings.json 中配置:
{
"Kestrel": {
"Endpoints": {
"HttpLoopback": {
"Url": "http://localhost:5002"
},
"HttpAny": {
"Url": "http://*:5003"
},
"HttpsDefaultCert": {
"Url": "https://localhost:5004"
},
"HttpsInlineCertFile": {
"Url": "https://*:5005",
"Certificate": {
"Path": "testCert.pfx",
"Password": "testPassword"
}
}
}
}
}
这样做的好处是允许完全从 IConfiguration 配置应用程序的绑定和 HTTPS 证书配置。这意味着你也可以利用安全的秘密存储,比如 Key Vault,来存储你的证书和证书密码。如果你使用上面的 appsettings.json 配置,你根本不需要调用 ConfigureKestrel()。
总结
在这篇文章中,我展示了8种设置你的应用程序监听的地址不同方法。UseUrls() 和 WebApplication.Urls 是最简单的方法,但通常单独使用并不适合生产环境 --urls、--http_ports 和 --https_ports 命令行参数以及 ASPNETCORE_/DOTNET_ 环境变量在生产中设置值最为有用。launchSettings.json文件非常适用于在开发环境中设置 URL。如果你需要对配置进行更细粒度的控制,你可以直接使用 Kestrel 的 Listen* 选项。这些也可以从配置中加载,以便在生产和开发环境中轻松使用。
源文地址:https://andrewlock.net/8-ways-to-set-the-urls-for-an-aspnetcore-app/
github地址:https://github.com/bingbing-gui/Asp.Net-Core-Skill