Reputation: 3476
I want Kestrel to automatically select a port. My Program.cs looks like this:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
var builder = webBuilder.UseStartup<Startup>();
if (args.Contains("--automatic-port-selection"))
{
builder.UseUrls("http://127.0.0.1:0");
}
});
I looked at https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1 to understand how I can detect the selected port. But I would actually like to obtain the port when the software starts.
I tried with the following:
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services) { }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
var serverAddressesFeature =
app.ServerFeatures.Get<IServerAddressesFeature>();
if (serverAddressesFeature != null)
{
foreach (var address in serverAddressesFeature.Addresses)
{
int port = int.Parse(address.Split(':').Last());
Console.Out.WriteLine("Port:" + port);
}
Console.Out.Flush();
}
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); }); });
}
}
You can see this basically just a aspnet core application created from the Visual Studio template.
The issue here is that it will always only writes 0. It seems it would only be able to give the correct port number when I read serverAddressesFeature
. Addresses` when handling a request. How can I get the used port number when starting up the server?
EDIT
This seems to be relevant: https://github.com/aspnet/Hosting/issues/1390
Upvotes: 2
Views: 1026
Reputation: 27997
As far as I know, the reason why you always get the 0 port number is the application doesn't started completely.
When the application started, it will call the startup.cs configure method firstly. This time Kestrel know that its port is 0.
After that it will find the auto free port.
So if you want to get the port which your application is using now. You could write a method which will fired after the application stated completely to log the right port.
More details, you could refer to below codes:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime , IServiceProvider serviceProvider){
//other codes ....
lifetime.ApplicationStarted.Register(
() => LogAddresses(app.ServerFeatures));
}
static void LogAddresses(IFeatureCollection features)
{
var addressFeature = features.Get<IServerAddressesFeature>();
if (addressFeature != null)
{
foreach (var address in addressFeature.Addresses)
{
int port = int.Parse(address.Split(':').Last());
Console.Out.WriteLine("Port:" + port);
}
}
}
Result:
Upvotes: 4