Reputation: 9489
The "hosting" mechanism has changed in .NET 6. Previously IWebHost
had IWebHost.ServerFeatures
property that could be used to get the IServerAddressFeature
like so (from this SO answer):
IWebHost host = new WebHostBuilder()
.UseStartup<Startup>()
.UseUrls("http://*:0") // This enables binding to random port
.Build();
host.Start();
foreach(var address in host.ServerFeatures.Get<IServerAddressesFeature>().Addresses) {
var uri = new Uri(address);
var port = uri.Port;
Console.WriteLine($"Bound to port: {port}");
}
Now in .NET 6 I have an IHost
. How do I get the port (line with ???
):
public class Program {
public static void Main(string[] args) {
IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args);
hostBuilder.ConfigureWebHostDefaults(webHostBuilder => {
webHostBuilder.ConfigureKestrel(opts => {
opts.ListenAnyIP(0); // bind web server to random free port
});
webHostBuilder.UseStartup<Startup>();
});
IHost host = hostBuilder.Build();
host.Start();
// If it doesn't fail, at this point Kestrel has started
// and is listening on a port. It even prints the port to
// console via logger.
int boundPort = ???; // some magic GetPort(IHost host) method
// This link in the docs mentions getting the port, but the example
// they provide is incomplete
// https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/endpoints?view=aspnetcore-6.0#port-0
host.WaitForShutdown();
}
}
When the port number 0 is specified, Kestrel dynamically binds to an available port. The following example shows how to determine which port Kestrel bound at runtime:
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
In this example, what is the app
? Where can I get that context
with .Features
?
Upvotes: 5
Views: 2871
Reputation: 9489
Found a working answer right after posting the question.
Function to print the address of a runing web server (including port) in .NET 6.
Turns out we're interested in a running instance of a IServer
service in the host.
public static void PrintBoundAddressesAndPorts(IHost host)
{
Console.WriteLine("Checking addresses...");
var server = host.Services.GetRequiredService<IServer>();
var addressFeature = server.Features.Get<IServerAddressesFeature>();
foreach(var address in addressFeature.Addresses)
{
var uri = new Uri(address);
var port = uri.Port;
Console.WriteLine($"Listing on [{address}]");
Console.WriteLine($"The port is [{port}]");
}
}
Found the answer in this article: https://andrewlock.net/finding-the-urls-of-an-aspnetcore-app-from-a-hosted-service-in-dotnet-6/
Upvotes: 6