【问题标题】:Configuration.GetSection always returns Value property nullConfiguration.GetSection 始终返回 Value 属性 null
【发布时间】:2018-02-11 13:02:12
【问题描述】:

每次调用Configuration.GetSection,返回对象的Value属性始终为null。

我的Startup 构造函数

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddEnvironmentVariables();

    this.Configuration = builder.Build();
}

我的ConfigureServices 方法

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<SqliteSettings>(opts => Configuration.GetSection("SqliteSettings").Bind(opts));

    services.AddOptions();

    services.AddMvc();
}

我的appsettings.json

{
  "SqliteSettings": {
    "DataSource": "C:\\db.sqlite",
    "NewDatabase": true,
    "Version": 3
  }
}

我用来定义 SqliteSettings 的类

public class SqliteSettings
{
    public string DataSource { get; set; }

    public bool? NewDatabase { get; set; }

    public int? Version { get; set; }

    public string Password { get; set; }

    public long? CacheSize { get; set; }

    // More properties
}

我在想 JSON 可能需要具有相同数量的属性才能匹配,或者它可能与数据类型定义有关,但也许这些完全不相关。

【问题讨论】:

    标签: c# asp.net-core .net-core


    【解决方案1】:

    根据Microsoft Docs

    当 GetSection 返回匹配的部分时,不会填充值。一种 节存在时返回 Key 和 Path。

    如果您想查看该部分的值,您需要调用 GetChildren() 方法:Configuration.GetSection("SqliteSettings").GetChildren();

    或者你可以使用: Configuration.GetSection("SqliteSettings").Get&lt;SqliteSettings&gt;()。 JSON 不需要具有相同数量的属性来匹配。不匹配的可空属性将被设置为空,不可为空的不匹配属性将被设置为其默认值(例如 int 将被设置为 0)。

    【讨论】:

    • Configuration.GetSection("SqliteSettings").Bind(sqliteSettingsObject);是另一种读取设置的方式
    • 如果只需要查看section是否存在,可以使用Exists()方法,如Configuration.GetSection("SqliteSettings").Exists()
    • .Get() 版本对我来说效果很好。令人沮丧的是,MSDN 只显示了一个 As cast in use,我敢打赌这会让很多人感到困惑。
    【解决方案2】:
    1. 右键单击appsettings.json 并转到“属性”。
    2. 选择复制到输出目录 = 始终复制。

    【讨论】:

    • 这么简单的事情浪费了这么多时间.....谢谢。
    【解决方案3】:

    只需将您的 ConfigureServices 方法修改为如下所示:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddOptions();
    
        services.Configure<SqliteSettings>(Configuration.GetSection("SqliteSettings"));
    
        services.AddMvc();
    }
    

    它应该可以工作。

    【讨论】:

    • 不幸的是,没有工作,尽管下订单可能解决了将来会出现的错误。 Configuration.GetSection 仍然返回,.Value 为空。
    • 你能分享一下你是怎么打电话给.Value的吗?
    • 要查看我是否获得了 JSON,只需执行 var x = Configuration.GetSection("SqliteSettings"); 然后在 Visual Studio 中检查 x,特别是 Value
    • 如果您想直接从Configuration 阅读,请使用Configuration["SqliteSettings:DataSource"]; 之类的内容。如果你想在控制器中使用它,请使用 options pattern
    • 我了解到,在 Startup.cs 中,您只能获取配置 json 的“叶子”,这与 .net core 1 左右不同,并使用这样的代码: services_.Configure( options_ => { options_ .Name = Configuration.GetValue("Corporate:Name"); options_.BrandLogo = Configuration.GetValue("Corporate:BrandLogo"); });
    【解决方案4】:

    如果所有其他答案都不能解决问题,另一个原因可能是 Options 类的属性是私有的(或者没有可访问的设置器)。

    【讨论】:

    • 非常感谢。显然,internal 不足以用于此目的。
    • 非常感谢,我只为设置类属性定义了getter。
    【解决方案5】:

    这在控制台应用程序中对我有用:

    var connectionString = config["ConnectionStrings:DefaultConnection"]
    

    【讨论】:

      【解决方案6】:

      我的问题是 .bind() 方法的对象实例没有初始化。

      services.Configure<SqliteSettings>(opts => Configuration.GetSection("SqliteSettings").Bind(opts));
      

      所以在调用 .bind(opts); 之前我初始化了值:

      SqlliteSettings opts = new SqliteSettings();
      

      绑定本地设置变量:

      Configuration.GetSection(AppSettingsSectionName).Bind(opts);
      

      并且分别做了容器注册:

      services.Configure<AppSettings>(Configuration.GetSection("SqlliteSettings"));
      

      这解决了问题,因为 .Bind() 方法只会在提供的实例为 null 时返回 null。

      【讨论】:

      • 天啊。你是英雄,MS是哑巴。如果要设置值,为什么不初始化?
      【解决方案7】:
      var serviceProvider = services.BuildServiceProvider();
      

      必须在所有services.Configure 呼叫之后来。

      【讨论】:

      • 你不应该手动构建服务提供者。
      【解决方案8】:

      如果你的依赖注入失败了,你在调试之后断定是这个方法的问题,那就不是!

      注册就够了:

      services.Configure<SqliteSettings>(Configuration.GetSection("SqliteSettings"));
      

      你必须在IOptions 接口中注入你的配置类。这将解决DI问题。我在这个问题上浪费了几个小时,希望对其他人有所帮助。

      【讨论】:

      • 你是怎么做到的?
      • @EduCielo 注入 IOptions
      【解决方案9】:

      确保您的配置对象上有属性访问器,否则将无法正确绑定。知道这一点今天会为我节省 2 个小时。

      public class MyConfiguration
      {
              public string ConfigurationOption1; // BAD
              public string ConfigurationOption2 { get; set; } // GOOD
      }
      

      【讨论】:

        【解决方案10】:

        对于 Web Api Core 2.1,我需要项目根文件夹(与 Startup.cs 相同的文件夹)中的 Program.cs

        【讨论】:

          【解决方案11】:

          尝试将 ConfigurationProvider 添加到 ConfigurationBuilder。

          应用配置来自:

          • appsettings.json 使用文件配置提供程序。
          • appsettings.{Environment}.json 使用文件配置提供程序。

          【讨论】:

            【解决方案12】:

            确保您不会意外地将变量嵌套在默认的 Logging 对象中。我一直在错误级别的括号中粘贴各种变量(但在默认的 appsettings.json 中意外正确),导致神秘地缺少键/值。

            【讨论】:

              【解决方案13】:

              就我而言,我使用的是 VS Code 和 .net core 3.x webapp。

              我遇到了类似的问题,GetSection() 或 Configuraton["Section:KeyName"] 返回 null, 我检查了 GetSection().Exists(),它也返回了 false。

              所以我尝试在 ConfigureServices 中添加 configbuilder 来帮助我解决这个问题,

                public void ConfigureServices(IServiceCollection services)
                {
                    //Initialize the builder 
                    var builder = new ConfigurationBuilder()
                                  .SetBasePath(Environment.CurrentDirectory)
                                  .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                                  .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true)//To specify environment
                                  .AddEnvironmentVariables();//You can add if you need to read environment variables.
              
                    //Build the configuration
                    IConfiguration Configuration = builder.Build();
              
                     
                    services.Configure<SqliteSettings>(Configuration.GetSection("SqliteSettings"));
                    //Similar to below 
                    //services.Configure<EntityClass>(Configuration.GetSection("EntityConfigSection"));
                    
                }
              

              注意:请确保 .VScode/launch.json 下的 cwd 和 program 的值正确。 代码从 cwd 值中选择当前工作目录,因此我们需要确保其设置正确。

              {
              // Use IntelliSense to learn about possible attributes.
              // Hover to view descriptions of existing attributes.
              // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
              "version": "X.X.X",
              "configurations": [
                  {
                      "name": ".NET Core Launch (web)",
                      "type": "coreclr",
                      "request": "launch",
                      "preLaunchTask": "build",
                      "program": "${workspaceFolder}/<ProjectLocation>/bin/<BuildType>/<Version>/<ProjectDll>",
                      "args": [],
                      "cwd": "${workspaceFolder}/<ProjectLocation>",
                      "stopAtEntry": false,
                      "serverReadyAction": {
                          "action": "openExternally",
                          "pattern": "\\bNow listening on:\\s+(https?://\\S+)"
                      },
                      "env": {
                          "ASPNETCORE_ENVIRONMENT": "Development"
                      },
                      "sourceFileMap": {
                          "/Views": "${workspaceFolder}/Views"
                      }
                  }
              
              ]}
              

              【讨论】:

                【解决方案14】:

                确保将代码添加到正确的 appsettings.json 文件中。 可能有多个 appsettings.json 文件,如 appsettings.Development.json、appsettings.QA.json,具体取决于项目,因此根据环境,您的代码将被执行。

                【讨论】:

                  【解决方案15】:

                  如果您有appsettings.Development.json 文件,请确保appsettings.Development.jsonappsettings.json 文件中的“ConnectionStrings:DefaultConnection”设置相同。

                  【讨论】:

                  • 谢谢:appsettings.Development.json 文件存在于我的源文件夹中,但未在 VS2019 中显示。
                  猜你喜欢
                  • 2018-02-24
                  • 1970-01-01
                  • 2011-08-18
                  • 2018-02-12
                  • 2020-05-24
                  • 2019-05-27
                  • 2021-09-16
                  • 1970-01-01
                  • 2016-05-31
                  相关资源
                  最近更新 更多