Kestrel http server 如何确定在指定动态端口(0)时ASP.NET Core 2正在侦听的端口
我有一个ASP.NET Core 2.0应用程序,我打算作为一个独立的应用程序运行。应用程序应启动并绑定到可用端口。为了实现这一点,我将WebHostBuilder配置为侦听“”并使用Kestrel服务器。一旦web主机开始侦听,我想将url与实际端口一起保存在一个文件中。我希望尽早这样做,因为另一个应用程序将读取该文件以与我的应用程序交互Kestrel http server 如何确定在指定动态端口(0)时ASP.NET Core 2正在侦听的端口,kestrel-http-server,asp.net-core-2.0,Kestrel Http Server,Asp.net Core 2.0,我有一个ASP.NET Core 2.0应用程序,我打算作为一个独立的应用程序运行。应用程序应启动并绑定到可用端口。为了实现这一点,我将WebHostBuilder配置为侦听“”并使用Kestrel服务器。一旦web主机开始侦听,我想将url与实际端口一起保存在一个文件中。我希望尽早这样做,因为另一个应用程序将读取该文件以与我的应用程序交互 如何确定web主机正在侦听的端口?我可以使用反射(啊!)。我已经注册了一个IHostedService并注入了IServer。KestrelServerOp
如何确定web主机正在侦听的端口?我可以使用反射(啊!)。我已经注册了一个
IHostedService
并注入了IServer
。KestrelServerOptions
上的ListenOptions
属性是内部的,因此我需要使用反射来访问它。调用托管服务后,我使用以下代码提取端口:
var options = ((KestrelServer)server).Options;
var propertyInfo = options.GetType().GetProperty("ListenOptions", BindingFlags.Instance | BindingFlags.NonPublic);
var listenOptions = (List<ListenOptions>)propertyInfo.GetValue(options);
var ipEndPoint = listenOptions.First().IPEndPoint;
var port = ipEndPoint.Port;
int Url = new System.Uri(Configuration["urls"]).Port;
var选项=((KestrelServer)服务器);
var propertyInfo=options.GetType().GetProperty(“ListenOptions”,BindingFlags.Instance | BindingFlags.NonPublic);
var listenOptions=(列表)propertyInfo.GetValue(选项);
var ipEndPoint=listenOptions.First().ipEndPoint;
var port=ipEndPoint.port;
您可以在方法配置的启动类中实现它。您可以从ServerAddressesFeature获取端口
下面是一个代码示例:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ILogger<Startup> logger)
{
var serverAddressesFeature = app.ServerFeatures.Get<IServerAddressesFeature>();
loggerFactory.AddFile("logs/myfile-{Date}.txt", minimumLevel: LogLevel.Information, isJson: false);
logger.LogInformation("Listening on the following addresses: " + string.Join(", ", serverAddressesFeature.Addresses));
}
public void配置(IApplicationBuilder应用程序、IHostingEnvironment环境、ILoggerFactory loggerFactory、ILogger logger)
{
var serverAddressesFeature=app.ServerFeatures.Get();
loggerFactory.AddFile(“logs/myfile-{Date}.txt”,minimumLevel:LogLevel.Information,isJson:false);
logger.LogInformation(“侦听以下地址:”+string.Join(“,”,serverAddressesFeature.addresses));
}
您可以使用Start()
方法而不是Run()
在适当的时候访问ISERVERAddresssFeature
:
IWebHost webHost = new WebHostBuilder()
.UseKestrel(options =>
options.Listen(IPAddress.Loopback, 0)) // dynamic port
.Build();
webHost.Start();
string address = webHost.ServerFeatures
.Get<IServerAddressesFeature>()
.Addresses
.First();
int port = int.Parse(address.Split(':').Last());
webHost.WaitForShutdown();
IWebHost webHost=new WebHostBuilder()
.UseKestrel(选项=>
options.Listen(IPAddress.Loopback,0))//动态端口
.Build();
webHost.Start();
字符串地址=webHost.ServerFeatures
.Get()
.地址
.First();
int port=int.Parse(address.Split(':').Last());
webHost.WaitForShutdown();
我可以在StartUp.cs中使用以下代码完成此操作:
var options = ((KestrelServer)server).Options;
var propertyInfo = options.GetType().GetProperty("ListenOptions", BindingFlags.Instance | BindingFlags.NonPublic);
var listenOptions = (List<ListenOptions>)propertyInfo.GetValue(options);
var ipEndPoint = listenOptions.First().IPEndPoint;
var port = ipEndPoint.Port;
int Url = new System.Uri(Configuration["urls"]).Port;
至少从.NETCore3中,您可以注入
IServer
并获取信息
using System;
using System.Linq;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
namespace MyApp.Controllers
{
public class ServerInfoController : Controller
{
public ServerInfoController (IServer server)
{
var addresses = server.Features.Get<IServerAddressesFeature>()?.Addresses?.ToArray();
}
}
}
使用系统;
使用System.Linq;
使用Microsoft.AspNetCore.Hosting.Server;
使用Microsoft.AspNetCore.Hosting.Server.Features;
名称空间MyApp.Controllers
{
公共类ServerInfoController:控制器
{
公共服务器InfoController(IServer服务器)
{
var addresses=server.Features.Get()?.addresses?.ToArray();
}
}
}
有0个地址,你知道为什么吗?你确定@jjxtra?它是枚举器,所以您必须执行以下操作:foreach(serverAddressesFeature.Addresses中的var地址)Console.WriteLine(address.ToString())
而不是使用Console.ReadKey()
使用webHost.WaitForShutdown()
您应该使用int.Parse(address.Split(':').Last())
由于地址可以定义为IPv6地址,因此如果您希望在获取地址之前在控制台/输出中打印默认消息,也可以使用webHost.RunAsync()
而不是webHost.Start()
。如果在两个端口(一个用于HTTP,另一个用于HTTPS)上侦听,则此操作将不起作用对于.NET Core 3.1Configuration[“URL”]
而言,在Startup.Configure()
中返回null,因此此建议似乎不起作用。这是一个不完整的答案。。无法解析类型为“Microsoft.AspNetCore.Hosting.Server.IServer”的服务@Gabrieluca如果未调用WebHost.CreateDefaultBuilder
,则可能存在未注册IServer
的问题ConfigureKestrel
不注册IServer
,但UseKestrel
和CreateDefaultBuilder
do。我也调用了WebHost.CreateDefaultBuilder,但仍然无法工作。。。我会收回我的反对票,因为。。。奇怪的是M$是如何改变事情的,而这么简单的事情很难做到。。得到。。我不能改变我的投票,除非你改变答案。。。它不允许我如果你能让它工作的话。。发布一个小样本,这会有所帮助。。