【问题标题】:How to configure Kestrel urls in startup class如何在启动类中配置 Kestrel url
【发布时间】:2017-05-21 18:21:02
【问题描述】:

我正在尝试找出正确的方法来修改 kestrel 侦听的 URL从 Startup 类构造函数

更新:除了下面的答案,我开始了解到 Startup 类并没有像我想象的那样用于配置 Kestrel。我曾认为 Startup 会创建一个单一的应用程序范围的配置对象,该对象将通过约定进行定位,但事实并非如此。正如@Tseng 指出的那样,应用程序和托管的配置是独立的关注点。链接的答案和接受的答案提供了工作示例。

我在 Vagrant 中启动了一个全新的 Ubuntu 14 机器,并根据 Microsoft 当前的说明安装了 ASP.NET Core 1.1:https://www.microsoft.com/net/core#linuxubuntu

我跑了:

  • dotnet new -t web
  • dotnet 恢复
  • dotnet 运行

默认情况下,这会在 http://localhost:5000 上侦听。在 Program.cs 中,我可以调用 app.UseUrls("http://*:5001) 来更改 URL 和端口。

我真正想要的是通过在 Startup 类中添加一个新的 JSON 设置文件来按照约定更改 URL,所以我按照示例创建了一个 hosts.JSON 文件(注意:我试过“server.urls " 和 "urls" 作为键)。

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

在 Startup.cs 下面的默认行添加我添加的 appsettings.json 文件 .AddJsonFile("hosting.json", optional: false); (可选:false 以确保它正在拾取文件)

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();
}

我已经验证配置构建后设置存在,但在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();
  }
}

并且应用程序仍然开始在 localhost:5000 上侦听。我(可能不正确)的理解是,通过使用正确的键正确命名设置,WebHostBuidler 应该选择它并使用它。

我已经看到其他示例基本上摆脱了启动类并在 Program.cs 中创建配置,然后可以将其传递到对 UseConfiguration 的调用中,但我的理解是,使用启动类应该按照惯例这样做。

基本上我想将启动和程序分开,将一个 hosts.JSON 文件添加到带有 URL 的配置中,然后在不需要的情况下拾取和使用它调用 UseUrls、UseConfiguration 等。

我是否遗漏了一些明显的东西,或者试图做一些实际上不正确的事情?

根据我的评论解释为什么这不是重复的:

  • 该帖子明确指出“launcherSettings 适用于 Visual Studio F5”。我在 Linux 机器上使用命令行。与VS无关。

  • 该帖子中提供的解决方案将配置构建移动到 main 方法中。我特别声明我想在 Startup 类中构建我的配置,就像默认的“dotnet new -t web”项目一样。

我不认为这是重复的,我仍在审查 ASP.NET Core 源代码,看看这是否可行。

关于正确的密钥:

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";

【问题讨论】:

  • 正确的字符串是顺便说一句。 server.urls,但我不确定它是否只能在启动时工作,如果那已经太晚了。使用链接的它肯定会工作(在 main 方法中读取托管并将其传递给网络构建器)
  • 阅读答案,它涵盖了完全相同的内容,并处理有关为红隼设置端口的问题。发布者最初只是被启动器设置弄糊涂了
  • 无论如何,问题表明我不想非常明确地将配置移出启动。如果 100% 确定不可能,那么这就是答案,但这是一个不同的问题。
  • @Tseng 我现在已经让我的问题的特定部分变得更加大胆,我已经添加了解释,我已经表明我一直在研究来源,我已经声明我已经尝试过这些方法。我不确定如何才能更清楚地表明这是一个不同的问题,即使我追求的结果是相同的。我想以不同的方式来处理它。您说“我不确定它是否只能在启动时工作,如果那已经太晚了”这正是我想要回答的问题。

标签: asp.net-core kestrel-http-server


【解决方案1】:

在您的 hosting.json 文件中,您应该使用 server.urls 而不是 urls。并且hosting.json文件需要添加在program.cs中(在main方法中)而不是在启动中。

这是我的 hosting.json 文件。

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

这是 Main 方法。

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();
}

这是截图。

【讨论】:

  • 谢谢,我知道这种技术是有效的,但是根据我原来的帖子,我正在寻找一种方法来保持启动和程序的分离。我想在 Startup 中保留配置,因为它在使用 dotnet new -t web 创建的默认项目中。我不明白为什么配置 Urls 需要将配置移动到 Program 或 Main 类中。
  • @Steve:因为这两种配置不相关。一个用于您的应用程序,另一个仅与托管相关。他们只是碰巧使用相同的配置框架/库来实现它。也可以使用命令行或环境变量来设置端口,所有方法都在链接答案(不是帖子)
  • @Tseng 谢谢!我错误地认为 Startup 可用于创建一个全局配置实例,该实例将通过约定由应用程序的其余部分定位。在源代码中花费最后一个小时并考虑到此评论提供了更深入的理解。问题是没有人真正说“你不能按照你的想法那样做”,而是提供了没有解决我的问题的替代解决方案。你能把你的评论变成我能接受的答案吗?
  • @Steve:接受这个,我在评论中链接的答案已经存在于其他用户中。我们在这里不仅仅是为了收集声誉 ;)
  • .AddCommandLine(args) 应该在.AddJsonFile("hosting.json", optional: true) 之后,否则您无法使用控制台参数覆盖配置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 2020-04-20
相关资源
最近更新 更多