Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure Kestrel urls in startup class

I am trying to figure out the proper way to modify the URL(s) that kestrel listens on from the Startup class constructor.

Update: In addition to the answer below, I've come to understand that Startup class isn't used to configure Kestrel in the way I had thought. I had thought that Startup would create a single application-wide configuration object that would be located through convention, it is not. As @Tseng points out, the configuration of the Application and Hosting are separate concerns. The linked answer and accepted answer provide working examples.

I spun up a brand new Ubuntu 14 box in Vagrant and installed ASP.NET Core 1.1 according to the current instructions from Microsoft: https://www.microsoft.com/net/core#linuxubuntu

I ran:

  • dotnet new -t web
  • dotnet restore
  • dotnet run

This listens on http://localhost:5000 by default. In Program.cs I can call app.UseUrls("http://*:5001) and this works to change the URL and port.

What I really want is to change the URLs by convention through adding a new JSON setting file in the Startup class, so I followed examples and created a hosting.JSON file with this (note: I've tried "server.urls" and "urls" as the key).

{
  urls: "http://*:5001"
}

In Startup.cs below the default lines for adding the appsettings.json files I added .AddJsonFile("hosting.json", optional: false); (optional: false to make sure it was picking up the file)

public Startup(IHostingEnvironment env)
{
  var builder = new ConfigurationBuilder()
  .SetBasePath(env.ContentRootPath)
  .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
  .AddJsonFile("hosting.json", optional: false);
  if (env.IsDevelopment())
  {
    // For more details on using the user secret store see https://go.microsoft.com/fwlink/?LinkID=532709
    builder.AddUserSecrets();
  }

  builder.AddEnvironmentVariables();
  Configuration = builder.Build();
}

I have verified that the setting is there after the configuration builds, but it is not picked up or used when the host is built in the Program.cs

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

    host.Run();
  }
}

and the application still starts listening on localhost:5000. It is my (likely incorrect) understanding that by having a setting properly named with the correct key the WebHostBuidler should pick it up and use it.

I've seen other examples that basically get rid of the startup class and create the configuration in Program.cs where it can then be passed into a call to UseConfiguration but again my understanding is that using a Startup class should do this by convention.

Essentially I'd like to keep Startup and Program separate, add a hosting.JSON file to the configuration with URLs, and have it picked up and used without needing to call UseUrls, UseConfiguration, etc.

Am I missing something obvious, or trying to do something that is not actually correct?

To explain why this is not a duplicate as per my comment:

  • That post specifically says "launcherSettings is for Visual Studio F5". I am using the command line on a Linux box. Nothing to do with VS.

  • The solution provided in that post moved the configuration build into the main method. I specifically state that I want to build my configuration in the Startup class just like the default "dotnet new -t web" project.

I do not feel this is a duplicate, and am still reviewing the ASP.NET Core source to see if this is possible.

In regards to the correct key:

https://github.com/aspnet/Hosting/blob/b6da89f54cff11474f17486cdc55c2f21f2bbd6b/src/Microsoft.AspNetCore.Hosting.Abstractions/WebHostDefaults.cs

namespace Microsoft.AspNetCore.Hosting
{
  public static class WebHostDefaults
  {
    public static readonly string ApplicationKey = "applicationName";
    public static readonly string StartupAssemblyKey = "startupAssembly";
    public static readonly string DetailedErrorsKey = "detailedErrors";
    public static readonly string EnvironmentKey = "environment";
    public static readonly string WebRootKey = "webroot";
    public static readonly string CaptureStartupErrorsKey = "captureStartupErrors";
    public static readonly string ServerUrlsKey = "urls";
    public static readonly string ContentRootKey = "contentRoot";
  }
}

https://github.com/aspnet/Hosting/blob/80ae7f056c08b740820ee42a7df9eae34541e49e/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs

public class WebHost : IWebHost
{
  private static readonly string DeprecatedServerUrlsKey = "server.urls";
like image 604
Steve Avatar asked Jan 06 '17 21:01

Steve


People also ask

What configure () method does in startup CS?

The Configure method is used to specify how the app responds to HTTP requests. The request pipeline is configured by adding middleware components to an IApplicationBuilder instance. IApplicationBuilder is available to the Configure method, but it isn't registered in the service container.

How do I start a Kestrel server?

To start the application from Kestrel webserver click project name menu item in run dropdown like below. ASPNETCoreVS2017Demo is my project name. This will start the app directly form Kestrel webserver. This will start the app with Kestrel webserver and server will start listening to port 5000 by default.

Is Kestrel used by default?

Kestrel is the web server that's included and enabled by default in ASP.NET Core project templates. Kestrel supports the following scenarios: HTTPS.


1 Answers

In your hosting.json file you should use server.urls instead of urls. And hosting.json file need to added in the program.cs (in the main method) not in startup.

Here is my hosting.json file.

{
  "server.urls": "http://localhost:5010;http://localhost:5012"
}

Here is the Main method.

public static void Main(string[] args)
{
    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddCommandLine(args)
        .AddEnvironmentVariables(prefix: "ASPNETCORE_")
        .AddJsonFile("hosting.json", optional: true)
        .Build();

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

    host.Run();
}

And here is the screenshot.

Screenshot of ASP.NET Core app running

like image 157
Anuraj Avatar answered Nov 23 '22 22:11

Anuraj