Configuration.GetSection始终返回null

Lia*_*ler 24 c# .net-core asp.net-core

每次调用时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();
}
Run Code Online (Sandbox Code Playgroud)

我的ConfigureServices方法

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

    services.AddOptions();

    services.AddMvc();
}
Run Code Online (Sandbox Code Playgroud)

我的 appsettings.json

{
  "SqliteSettings": {
    "DataSource": "C:\\db.sqlite",
    "NewDatabase": true,
    "Version": 3
  }
}
Run Code Online (Sandbox Code Playgroud)

我用来定义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
}
Run Code Online (Sandbox Code Playgroud)

我认为JSON可能需要具有相同数量的属性才能匹配,或者它可能与数据类型定义有关,但可能与完全无关.

Iva*_*ich 21

根据Microsoft Docs的说法:“当GetSection返回匹配的节时,不会填充Value。当该节存在时,将返回Key和Path。”

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

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

  • 如果您只需要查看该部分是否存在,则可以使用 Exists() 方法,如 `Configuration.GetSection("SqliteSettings").Exists()` (9认同)
  • .Get&lt;&gt;() 版本对我来说效果很好。令人沮丧的是,MSDN 只显示了正在使用的 As 转换,我敢打赌这让很多人感到困惑。 (2认同)
  • 我不断获取该对象的实例,但所有属性均为空。事实证明,我在没有设置器的情况下定义了属性(即“public string MyString { get; }”),并且不允许 .NET 映射到我的对象 (2认同)

Ali*_*Ali 13

只需修改您的ConfigureServices方法如下:

public void ConfigureServices(IServiceCollection services)
{
    services.AddOptions();

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

    services.AddMvc();
}
Run Code Online (Sandbox Code Playgroud)

它应该工作.

  • 不幸的是,虽然下订单可能解决了将来会发生的错误,但是没有用.`Configuration.GetSection`仍然返回,`.Value`为null. (7认同)
  • 如果你想直接从`Configuration`读取,请使用类似`Configuration ["SqliteSettings:DataSource"];`.如果你想在控制器中使用**选项模式** (4认同)
  • 要查看我是否获得了JSON,只需执行`var x = Configuration.GetSection("SqliteSettings");然后在Visual Studio中检查x,特别是"Value". (3认同)

mr_*_*ala 8

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

services.Configure<SqliteSettings>(opts => Configuration.GetSection("SqliteSettings").Bind(opts));
Run Code Online (Sandbox Code Playgroud)

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

SqlliteSettings opts = new SqliteSettings();
Run Code Online (Sandbox Code Playgroud)

绑定本地设置变量:

Configuration.GetSection(AppSettingsSectionName).Bind(opts);
Run Code Online (Sandbox Code Playgroud)

并单独做了容器注册:

services.Configure<AppSettings>(Configuration.GetSection("SqlliteSettings"));
Run Code Online (Sandbox Code Playgroud)

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

  • 我的天啊。你是英雄,MS是笨蛋。如果要设置值,为什么不初始化? (2认同)

小智 7

  1. 右键单击appsettings.json并转到属性。
  2. 选择复制到输出目录=始终复制。

  • 这么简单的事情浪费了这么多时间……谢谢。 (2认同)

Tam*_*abó 7

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


Sam*_*meh 5

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

var connectionString = config["ConnectionStrings:DefaultConnection"]
Run Code Online (Sandbox Code Playgroud)