繁体   English   中英

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

[英]configuration.getValue or configuration.getsection always returns null

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

程序.cs

 WebHost.CreateDefaultBuilder(args)
 .ConfigureAppConfiguration((hostingContext, config) =>
 {
      config.SetBasePath(Directory.GetCurrentDirectory());
 })

启动文件

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

Web API 控制器

private readonly IConfiguration config;

public EmailController(IConfiguration configuration)
{
    if (configuration != null)
    {
        config = configuration;
    }
}

动作方法

var emailTemplatesRelativePath = config.GetSection("EmailSettings");
var email = config.GetValue<string>("Email");

以上两GetSectionGetSectionGetValue返回空值

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

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

Nuget:Microsoft.Extensions.Configuration.Binder

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

appsettings.json

{
  "EmailSettings": {
    "EmailTemplatesPath": "EmailTemplates",
    "Email": "aa@aa.com"
  }
}

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

电子邮件设置.cs

public class EmailSettings
{
    public string EmailTemplatesPath { get; set; }
    public string Email { get; set; }
}

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

启动文件

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

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

Web API 控制器

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

    public ValuesController(EmailSettings emailSettings)
    {
        _emailSettings = emailSettings;
    }
....
}

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

在 IIS(或 IIS Express)内托管进程内时, Directory.GetCurrentDirectory()将返回与运行out-of-process时返回的路径不同的路径。 在 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());
    })

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

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

您犯了一个简单的错误,忘记在“电子邮件设置”中添加“电子邮件”。 如下所示更新您的 json 并使用config.GetSection("EmailSettings")["Email"];

"EmailSettings": {
    "EmailTemplatesPath": "EmailTemplates",
    "Email": "aa@aa.com"
  },

希望这能解决您的问题。

编辑:

如果您想将这些值从 appsettings 获取到除启动之外的任何其他内容,您应该将这些配置值加载到设置类中,然后将适当的 IOptions 实例注入到您要使用这些设置的方法构造函数中。 为此,请在此处查看我的回答。

程序.cs

public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();

        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
             .UseStartup<Startup>();
    }

启动.cs:

public partial class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
        {
            app.UseMvcWithDefaultRoute();
        }
    }

控制器类

在此处输入图片说明

您需要使用 Bind() 方法从部分获取值。

EmailSetting option = new EmailSetting();
            //You need to bind the section with data model, 
            //it will automatically map config key to property of model having same name
            config.GetSection("EmailSettings").Bind(option);

            //Alternative to this you can read nested key using below syntax
            var emailTemplatesPath = config["EmailSettings:EmailTemplatesPath"];
            var emailInEmailSettings = config["EmailSettings:Email"];
            // If email key is not nested then you can access it as below
            var email = config.GetValue<string>("EmailOutside");

电子邮件设置模型:-(属性名称应与配置键匹配)

public class EmailSetting
    {
        public string EmailTemplatesPath { get; set; }
        public string Email { get; set; }
    }

Appsetting.json:-

    {
       "AllowedHosts": "*",
        "EmailSettings": {
            "EmailTemplatesPath": "EmailTemplates",
            "Email": "aa@aa.com"
          },
          "EmailOutside": "aa@aa.com"
        }

虽然其他人已经解决了这个问题,但如果您想保持启动服务代码不变,只需将您的 Web API 控制器更改为以下内容:

private readonly EmailSettings _emailSettings;

public EmailController(IOptions<EmailSettings> emailSettings)
{
    _emailSettings = emailSettings.Value;
}

重点是.Value 这就是您的代码返回 null 的原因。 我还建议将 program.cs 改回默认值。 要在操作方法中使用它,只需执行以下操作:

_email.settings.EmailTemplatesPath

最后一件事 - 确保您的 EmailSettings 类结构与您的 json 完全相同。

你可以做这样的事情

services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
services.AddTransient(p => p.GetRequiredService<IOptions<EmailSettings>>().Value);

并通过构造函数 DI 初始化 EmailSettings 对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM