借助ASP.NET Core 3.0,我已经能够使用此IHostedService
方法...
Determine port Kestrel binded to
...在运行时确定Kestrel的动态端口。
IServerAddressesFeature
在此处记录了ASP.NET 3.0:
但是,当将版本更改为ASP.NET Core 3.1时,页面将重定向回ASP.NET 3.0,并提示该文档不适用于ASP.NET Core 3.1。 IServerAddressesFeature
不再工作了吗?将IServerAddressesFeature
与ASP.NET Core 3.1一起使用仍然可以编译,但是返回的ServerAddresses
中的端口始终为零。
程序:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost().Run();
}
public static IWebHost BuildWebHost() =>
WebHost.CreateDefaultBuilder()
.UseKestrel()
.UseUrls("http://127.0.0.1:0") // port zero to use random dynamic port
.UseStartup<Startup>()
.Build();
}
稍后,当调用Configure
时...
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
HostedService.ServerAddresses = app.ServerFeatures.Get<microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>();
...如链接示例中所示,服务器地址已分配给HostedService.ServerAddresses
静态变量。但是,ServerAddresses
仅包含端口为零的环回地址:"http://127.0.0.1:0"
。
我在俯视什么吗? v3.1中是否有其他适当的方法来解决此问题?如何使用ASP.NET Core 3.1将Kestrel配置为使用随机动态端口并确定运行时该端口位于哪个端口(在执行任何控制器操作之前)?
更新
这是一个丑陋的解决方法,可帮助您确定端口。动态端口分配的时间或顺序似乎已更改。从HostedService.StartAsync
方法返回并稍后读取服务器地址似乎就足够了。当然必须有更好的方法吗?
public Task StartAsync(CancellationToken cancellationToken)
{
System.Threading.Tasks.Task.Run(async () =>
{
int port = 0;
while (port == 0)
{
// a single delay seems to be sufficient
await System.Threading.Tasks.Task.Delay(100);
var address = ServerAddresses.Addresses.Single();
// address in this app is always in form http://127.0.0.1:port
var pos = address.LastIndexOf(':');
var portString = address.Substring(pos + 1);
port = int.Parse(portString);
}
// have determined the dynamic port now
});
return System.Threading.Tasks.Task.CompletedTask;
}