configuration.getValue 或 configuration.getsection 总是返回 null

Nav*_*utt 5 .net c# .net-core asp.net-core asp.net-core-webapi

我是 .Net Core 的新手并试图从appsettings.json文件中获取一个值,但我错过了一些非常基本的东西。请让我知道我做错了什么......这是代码......

程序.cs

 WebHost.CreateDefaultBuilder(args)
 .ConfigureAppConfiguration((hostingContext, config) =>
 {
      config.SetBasePath(Directory.GetCurrentDirectory());
 })
Run Code Online (Sandbox Code Playgroud)

启动文件

public IConfiguration Configuration { get; private set; }
public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
}
Run Code Online (Sandbox Code Playgroud)

Web API 控制器

private readonly IConfiguration config;

public EmailController(IConfiguration configuration)
{
    if (configuration != null)
    {
        config = configuration;
    }
}
Run Code Online (Sandbox Code Playgroud)

动作方法

var emailTemplatesRelativePath = config.GetSection("EmailSettings");
var email = config.GetValue<string>("Email");
Run Code Online (Sandbox Code Playgroud)

以上两行都返回空值GetSectionGetValue

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Trace",
      "Microsoft": "Information"
    }
  },
  "ConnectionStrings": {
    "FCRContext": "server=xxx;database=xxx;user id=xxx;password=xxx"
  },
  "AllowedHosts": "*",
  "EmailSettings": {
    "EmailTemplatesPath": "EmailTemplates"
  },
  "Email": "aa@aa.com"
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*ele 5

访问 Controller 中的配置与 Startup.cs 中的配置略有不同。我前一段时间做了这个,只需按照以下步骤操作:

Nuget:Microsoft.Extensions.Configuration.Binder

将您要在控制器中访问的所有配置放入一个部分,例如“电子邮件设置”:

appsettings.json

{
  "EmailSettings": {
    "EmailTemplatesPath": "EmailTemplates",
    "Email": "aa@aa.com"
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的 Web API 项目中创建一个名为的类EmailSettings.cs

电子邮件设置.cs

public class EmailSettings
{
    public string EmailTemplatesPath { get; set; }
    public string Email { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后将您的配置值绑定到EmailSettings类的实例Startup.cs并将该对象添加到依赖注入容器:

启动文件

public void ConfigureServices(IServiceCollection services)
{
    ...
    EmailSettings emailSettings = new EmailSettings();
    Configuration.GetSection("EmailSettings").Bind(emailSettings);
    services.AddSingleton(emailSettings);
}
Run Code Online (Sandbox Code Playgroud)

现在您可以通过简单地将您的配置添加到构造函数中来请求您在 Api 控制器中的配置,如下所示:

Web API 控制器

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    EmailSettings _emailSettings;

    public ValuesController(EmailSettings emailSettings)
    {
        _emailSettings = emailSettings;
    }
....
}
Run Code Online (Sandbox Code Playgroud)

刚刚在我当前的项目(.NET Core 2.2 Web Api)中再次尝试了这个,并且成功了。我在 ValuesController 构造函数中放置了一个断点,并且 _emailSettings 对象包含appsettings.json文件中的值。您应该能够复制并粘贴这个!玩得开心!:)


Kir*_*kin 4

当在 IIS(或 IIS Express)内部托管进程Directory.GetCurrentDirectory()内时,将返回与进程外运行时返回的路径不同的路径。在 ASP.NET Core 2.1 之前,基于 IIS 的托管始终是进程外的,但 ASP.NET Core 2.2 引入了进程内运行的功能(这是创建新项目时的默认设置)。

在进程外运行时,Directory.GetCurrentDirectory()将返回 ASP.NET Core 应用程序本身的路径,而在进程内运行时,它将返回 IIS(或 IIS Express,例如“C:\Program Files\IIS Express”)的路径”)。

从你的问题来看,相关代码是这样的:

WebHost.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        config.SetBasePath(Directory.GetCurrentDirectory());
    })
Run Code Online (Sandbox Code Playgroud)

在这里,在您调用 之前SetBasePathIConfigurationBuilder已经设置为使用正确的路径。您的调用本身会覆盖此路径,将其设置为“C:\Program Files\IIS Express”。使用此覆盖的基本路径,appsettings.json将不再找到您的等文件,因为它们不在“C:\Program Files\IIS Express”等位置,因此不会从这些文件加载​​任何配置。

解决方案只是删除您的调用,ConfigureAppConfiguration以便基本路径不会被覆盖。我知道您已经发现了这一点,但我想确保您对这里出了什么问题有一个解释。