1

I'm working with an ASP.NET Core 1 RTM web app and I'm updating Kestrel setup to latest conventions. Setup aims at having the following sources for server.urls, from lowest to highest priority:

  1. URLs set in Program.Main() code (default, e.g. for production)
  2. URLs set in hosting.Development.json (e.g. to override default while developing)
  3. URLs set in environment variables (e.g. to override default for staging or other production env.)

As per latest references (e.g. here on SO and here on Github), this is what I got now:

ProjDir\Program.cs:

public class Program
{
    // Entry point for the application
    public static void Main(string[] args)
    {
        const string hostingDevFilepath = "hosting.Development.json";
        const string environmentVariablesPrefix = "ASPNETCORE_";

        string currentPath = Directory.GetCurrentDirectory();

        var hostingConfig = new ConfigurationBuilder()
            .SetBasePath(currentPath)
            .AddJsonFile(hostingDevFilepath, optional: true)
            .AddEnvironmentVariables(environmentVariablesPrefix)
            .Build();

        System.Console.WriteLine("From hostingConfig: " +
            hostingConfig.GetSection("server.urls").Value);

        var host = new WebHostBuilder()
            .UseUrls("https://0.0.0.0")
            .UseConfiguration(hostingConfig)
            .UseKestrel()
            .UseContentRoot(currentPath)
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}

ProjDir\hosting.Development.json:

{
    "server.urls": "http://localhost:51254"
}

From command line, having set ASPNETCORE_ENVIRONMENT=Development, this is the output:

> dotnet run

Project Root (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
From hostingConfig: http://localhost:51254
info: AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerMiddleware[0]
      An existing key was automatically added to the signing credentials list: <<yadda yadda yadda>>
Hosting environment: Development
Content root path: <<my project root dir>>
Now listening on: https://0.0.0.0:443
Application started. Press Ctrl+C to shut down.

My expected output would be instead Now listening on: http://localhost:51254. URLs value is correctly picked up from JSON source (as per console log), but then Kestrel configuration ignores that, even if UseConfiguration comes after UseUrls.

What am I missing? Thanks for your suggestions.

Community
  • 1
  • 1
superjos
  • 12,189
  • 6
  • 89
  • 134
  • What if you use `urls` as a name instead of `server.urls`? (https://github.com/aspnet/Hosting/blob/e7b8c3f90a781a55658b4245571c5bf5dac5e56e/src/Microsoft.AspNetCore.Hosting.Abstractions/WebHostDefaults.cs#L15) – Pawel Jul 11 '16 at 20:55
  • I just tried (re)adding both a `UseUrls()` and then set `urls` in Json sources. The settings from Json source is picked up correctly! Two questions? Q1: is this documented somewhere yet (apart from looking at the code :) ) Q2: how come that if there's no `UseUrls` then even `server.urls` works? Tnx – superjos Jul 11 '16 at 21:04
  • I believe it is being picked up automatically if it is configured. `UseUrls` allows you to configure urls programmatically. – Pawel Jul 11 '16 at 21:18
  • Yep, that I got it. It's this *new* setting name that I was not aware of. And it sounds strange UseUrls works with the new one and not with the old. But then again this just came out of RC ... Please feel free to reply this question. – superjos Jul 11 '16 at 21:25
  • I think it was changed post RC1 – Pawel Jul 11 '16 at 21:27

2 Answers2

2

Try using urls instead of server.urls. The name of the setting changed post RC2.

Pawel
  • 31,342
  • 4
  • 73
  • 104
  • The referenced change belongs to a commit tagged with 1.0.0, so probably was even post RC2, landing to RTM – superjos Jul 11 '16 at 21:43
1

Did some more tests. It seems to me that as soon as UseUrls() is present, no matter in which order, all Json config sources are ignored.

So I tried to come up with a solution supporting more than one hosting.json file, e.g. a default one and then one per environment. Basically I tried to replicate in Program.Main() a behavior similar to Startup.Startup(IHostingEnvironment env), where one can use both "appsettings.json" and $"appsettings.{hostingEnv.EnvironmentName}.json" as source. The only issue is that in Program.Main() there's no IHostingEnvironment available, but this GH issue reminded me that we still have Environment.GetEnvironmentVariable("some-variable") in our toolbelt.

Here's the full solution, please feel free to suggest improvements or (even better) some semplification:

public class Program
{
    // Entry point for the application
    public static void Main(string[] args)
    {
        const string environmentVariablesPrefix = "ASPNETCORE_";

        string hostingEnvironmentKey = $"{environmentVariablesPrefix}ENVIRONMENT";
        string hostingEnvironmentValue;

        try
        {
            hostingEnvironmentValue = Environment
                .GetEnvironmentVariable(hostingEnvironmentKey);
        }
        catch
        {
            hostingEnvironmentValue = "Development";
        }

        const string hostingFilepath = "hosting.json";
        string envHostingFilepath = $"hosting.{hostingEnvironmentValue}.json";

        string currentPath = Directory.GetCurrentDirectory();

        var hostingConfig = new ConfigurationBuilder()
            .SetBasePath(currentPath)
            .AddJsonFile(hostingFilepath, optional: true)
            .AddJsonFile(envHostingFilepath, optional: true)
            .AddEnvironmentVariables(environmentVariablesPrefix)
            .Build();

        var host = new WebHostBuilder()
            .UseConfiguration(hostingConfig)
            .UseKestrel()
            .UseContentRoot(currentPath)
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}
// in hosting.json
{
  "server.urls": "https://0.0.0.0"
}

// in hosting.Development.json
{
  "server.urls": "http://localhost:51254"
}
superjos
  • 12,189
  • 6
  • 89
  • 134