Setting host URI in ASP.NET Core 1.0 RC2

You will need this if you want to host multiple apps. on the same machine.

 May 26, 2016


It's an RC1 world!

Back in the RC1 days, you could just pass an argument on the command-line to set the host URI. It went like this:

> dnx web myapp --server.urls="http://localhost:10000/"

and your app would just run on the host (localhost) and port (10000) you specified. The configuration was read by KestrelServerInformation and utilized by ServerFactory. Additionally, you could also just specify a port and the host would default to localhost:

> dnx web myapp --HTTP_PLATFORM_PORT="10000"

This was handled by HostingEngine.

Here comes RC2!

With the introduction of RC2, if you try passing the same command-line arguments, you will find your app. ignores them:

> dotnet run --server.urls="http://localhost:10000/"
...
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

There are two ways to get the desired behavior–UseUrls and UseConfiguration.

UseUrls

You will need to add Microsoft.AspNetCore.Hosting as a dependency in project.json. Then, chain UseUrls to the WebHostBuilder-instance in Program.cs:

public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .UseUrls(args)
        .Build();

    host.Run();
}

Now, when you run your app.:

> dotnet run "http://localhost:10000/"
...
Now listening on: http://localhost:10000/

You could also setup several app.-instances by specifying multiple URIs separated by a semi-colon.

UseConfiguration

Going this route also requires the Microsoft.AspNetCore.Hosting package in addition to Microsoft.Extensions.Configuration.CommandLine. And, Program.cs now looks like this:

public static void Main(string[] args)
{
    var config = new ConfigurationBuilder()
        // These two are just additional ways to load configuration settings.
        // .AddEnvironmentVariables(prefix: "ASPNETCORE_") // `Microsoft.Extensions.Configuration.EnvironmentVariables`
        // .AddJsonFile("hosting.json", optional: true) // `Microsoft.Extensions.Configuration.Json`
        .AddCommandLine(args)
        .Build();

    var host = new WebHostBuilder()
        .UseConfiguration(config)
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();

    host.Run();
}
> dotnet run --server.urls="http://localhost:10000/"
...
Now listening on: http://localhost:10000/

You can drop the server-part and still get the expected outcome:

> dotnet run --urls="http://localhost:10000/"
...
Now listening on: http://localhost:10000/

Note: post-RC2, server.urls appears to be deprecated in favor of urls.

How does RC2 get the arguments?

When Build is called on the WebHostBuilder-instance, the method creates a new WebHost-instance. Inside this instance, the server.urls (via WebHostDefaults) configuration-key is read. Again, post-RC2, some of this behavior has been changed and can be found here.

Recap

If you have plans to host multiple apps. on the same machine, you will need to implement one of the configuration options. Otherwise, you will receive an error like:

Unhandled Exception: System.AggregateException: One or more errors occurred. (Error -4091 EADDRINUSE address already in use)