如何从 Asp.NET Core 3.1 启动类访问 launchSettings.json 中的 `applicationUrl` 属性?

Posted

技术标签:

【中文标题】如何从 Asp.NET Core 3.1 启动类访问 launchSettings.json 中的 `applicationUrl` 属性?【英文标题】:How Do You Access the `applicationUrl` Property Found in launchSettings.json from Asp.NET Core 3.1 Startup class? 【发布时间】:2019-12-18 18:53:32 【问题描述】:

我目前正在创建一个 Asp.NET Core 3.1 API 应用程序。其中,我有一个launchSettings.json,如下所示:


  "iisSettings": 
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": 
      "applicationUrl": "http://localhost:61392",
      "sslPort": 44308
    
  ,
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": 
    "IIS Express": 
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "weatherforecast",
      "environmentVariables": 
        "Key": "Value",
        "ASPNETCORE_ENVIRONMENT": "Development"
      
    ,
    "Application.API": 
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "weatherforecast",
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      ,
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    
  

特别是,我对获取此文件中定义的applicationUrl 值感兴趣。不幸的是,除了通过 JSON 序列化直接加载文件并探测那里的值之外,我没有看到任何明显的方式来访问它们。

因此,我正在寻找更优雅的解决方案。有没有办法从Startup.Configure 和/或Startup.ConfigureServices 方法中访问这些值?

我在想这样的事情:

public void Configure(IApplicationBuilder builder)

    var url = builder.ApplicationServices.GetRequiredService<IServerHostingEnvironment>().ApplicationUrl

作为参考,我确实看到了this question,但这似乎需要一个 HTTP 请求。就我而言,在发出请求之前,我仍在配置服务器。

对于进一步参考和上下文:我正在构建一个 .NET GitHub App 应用程序,并且正在制作 Smee.io 客户端的相应等效项,其 javascript 代码为 can be found here。

客户端获取source(通过服务器发送的事件)并将其发送到target。我找到并配置了source,但具有讽刺意味的是,我无法以明显的配置方式访问和建立target URL(上面的applicationUrl)。

最后,我意识到我可以硬编码appSettings.json 中的值,但这意味着我将在两个地方保持相同的值——一个在appSettings.json 中,一个在已经存在的launchSettings.json 中。如果可能的话,我宁愿把它放在一个地方以减少维护负担。

【问题讨论】:

根据我的理解,你不能。我假设 VS 只读取 launchSettings.json 以了解要使用的 URL,然后启动 Web 浏览器。但是,您的 Web 应用程序是在 IIS Express 上使用.vs 文件夹下的配置文件单独启动的,因此它只能从那里看到这些设置。有一种机制可以同步launchSettings.json 和 IIS Express 配置文件(从特定版本的 VS 开始),但这对您的 Web 应用程序也是透明的。 感谢您的洞察力,@LexLi。理想情况是同时适应本地开发 (IIS) 和生产。网络托管环境的这种基本和基本属性似乎在初始化期间可以访问并随时可用,但由于某种原因,它似乎是最难以捉摸的。 IHttpContextAccessor 是最接近的近似值,但在 Startup.Configure 期间是 null 您是否找到了解决方案,或者说 LexLi 的评论是最终决定? @ruffin 我最终在这里咬紧牙关,并在整个解决方案中复制了我的连接字符串/地址。比如它。不过,很高兴看到其他人也有同样的感受并想要更好的解决方案。 【参考方案1】:

其实我最近也在寻找类似的东西。

事实证明,您可以通过查看环境变量来确定 Visual Studio 在调试会话期间(从 launchSettings.json 中的 applicationUrl)将哪些 URL 传递给应用程序。

尽管请记住,这可能仅对使用 launchSettings.json 文件的 VStudio IDE 中的调试有用

var urls = Environment.GetEnvironmentVariable("ASPNETCORE_URLS").Split(";");

【讨论】:

记住可能的 NRE 并添加 ?: ("ASPNETCORE_URLS")?.Split(【参考方案2】:

尚未测试,但我使用此模式访问 appsettings.json。

在 startup.cs 中将 launchsettings.json 添加到配置生成器中:

public Startup(IConfiguration configuration)
    
        var builder = new ConfigurationBuilder().AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "Properties", "launchSettings.json"));
        Configuration = builder.Build();
    

public IConfiguration Configuration  get; 

将其添加为服务:

public void ConfigureServices(IServiceCollection services)

    services.AddSingleton <IConfiguration> (Configuration);

将其注入控制器并获取键值:

public class SomeController: ControllerBase   
    private IConfiguration _iconfiguration;  
    public SomeController(IConfiguration iconfiguration)   
        _iconfiguration = iconfiguration;  
    
void SomeMethod()
string appUrl = _iConfiguration.GetValue<string>("applicationUrl","someDefaultValue")

希望对您有所帮助!

【讨论】:

感谢您的回答。如果我理解正确,这依赖于不是首选的appSettings.json 文件。该信息位于launchSettings.json(或内存中的somewhere,因为它被IIS 服务器在某处使用),这就是我想要访问它的内容。 不,看第一个代码块。 var builder = new ConfigurationBuilder().AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "Properties", "launchSettings.json")); 好的,知道了...我现在和你在一起。如果另一个没有出现,这似乎是一种后备策略。如前所述,我知道我可以简单地反序列化配置文件中的值,并在IConfiguration API 周围寻找是这种情况的一种方式。我正在寻找的是核心框架代码使用和公开的这个值。像IApplicationBuilder.ApplicationServices.GetRequiredService&lt;IServerHostingEnvironment&gt;().ApplicationUrl 这样的东西。你会认为这个值在IWebHostEnvironment 中很容易获得,但是唉。 我现在明白了,我认为您只是想要一种更简洁的方法,而不是从文件中读取所有文本并以这种方式获取值,如果我偶然发现了什么,我会告诉您!【参考方案3】:

在您的Startup 构造函数中,您可以通过依赖注入获得IConfiguration。有了这个,您可以使用如下配置访问 appsettings.json 中的属性:

var appUrl = _configuration["profiles:applicationUrl"];

如果您要访问appsettings.json 中的许多属性,您可以使用IConfiguration.Bind() 方法将配置json 中的所有属性绑定到一个类实例。例如,您将拥有:

public class Config

   public Profile Profiles  get; set; 

public class Profile

   public string ApplicationUrl  get; set; 

然后在ConfigureServices

var config = new Config();
_configuration.Bind(config);

然后,如果您将配置注册到服务提供者中,您可以通过 DI 在任何地方访问您的配置:

services.AddSingleton(config);

编辑

要添加默认 appsettings.json 以外的 json 文件,请在下面记录的 Program.cs 中的 CreateDefaultBuilder 之后调用 IWebHostBuilder 上的 ConfigureAppConfiguration()

Link to File Configuration Docs

在回调参数中,您可以将任意数量的 json、xml、ini 文件添加到您想要的配置中,然后使用我上面的答案从所有文件中获取任何值。请注意,如果存在两个相同的键,则将使用该键的最后一个值。

【讨论】:

感谢您的回答。如果我理解正确,这将意味着使用appsettings.json,正如我在问题中提到的那样并不理想,因为然后我必须在两个位置管理相同的数据。如果我在这里误解了什么,请告诉我。 您可以执行@zonorai 提到的操作,并将launchSettings.json 作为json 文件添加到配置中,然后从配置的该部分访问该值。我添加了一个编辑以进一步解释这一点。 确实,如果没有给出另一个答案,那似乎是领先者。我更喜欢不使用 IConfiguration 并公开框架中定义和使用的属性,更具体地说,是托管 (IIS) 服务器。 您可能想要查看环境变量,然后从您的所有应用程序中访问它。【参考方案4】:

我知道,一年过去了,但这个解决方案可能对某人有用:

var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .AddEnvironmentVariables()
                .Build();
var appUrl = configuration["ASPNETCORE_URLS"].Split(";").First();

【讨论】:

以上是关于如何从 Asp.NET Core 3.1 启动类访问 launchSettings.json 中的 `applicationUrl` 属性?的主要内容,如果未能解决你的问题,请参考以下文章

源码解读asp.net core源码启动流程精细解读

Asp.net Core 3.1-如何从控制器返回到 Razor 页面?

如何在 ASP.NET Core 3.1 生产中配置 IdentityServer

如何从 ASP.NET Core 3.1 中的存储库类创建确认电子邮件回调

如何正确解析要在 ASP.NET Core 3.1 的 ConfigureServices() 中使用的服务?

如何使用 C# 在 ASP.NET Core 3.1 MVC 中使用会话变量