如何将 appsettings.json 中的 json 设置解析为 c# .net 核心中的 class

How to parse json settings in appsettings.json into a class in c# .netcore

我有一个 appsettings.json 看起来像这样

{
  "AppName": "my-app-service",
  "MyModel": {
    "MyList": [{
      "CountryCode": "jp"
    },{
      "CountryCode": "us"
    }]
  }
}

现在,我有一个 POCO 文件,(MyList.cs 被省略了,它有一个字符串键 countryCode)

public class MyModel
{
    public IList<MyList> MyList;
}

我希望能够将 MyModel 注入到我的代码中的任何位置,我该怎么做?我看到人们在 setup.cs

中这样做
    services.Configure<MyModel>(Configuration.GetSection("MyModel"));

当我在构造函数的代码中使用 IOption<MyModel> 时,它看起来如何,我只是得到空值。我哪里错了?

你是对的:调用 Configure<T>T 设置选项基础结构。这包括 IOptions<T>IOptionsMonitor<T>IOptionsSnapshot<T>。在其 最简单的 形式中,配置值使用 Action<T> 或在您的示例中绑定到特定 IConfiguration。您还可以 堆叠 多次调用 Configure 的任一形式。然后,这允许您在 class' 构造函数中接受 IOptions<T>(或 monitor/snapshot)。

确定绑定到 IConfigurationSection 是否按预期工作的最简单方法是手动执行绑定,然后检查值:

var opts = new MyClass();
var config = Configuration.GetSection("MyClass");
// bind manually
config.Bind(opts);
// now inspect opts

以上依赖于 Microsoft.Extensions.Configuration.Binder 包,如果您引用 Options 基础结构,您应该已经将其作为传递依赖项。

回到你的问题:活页夹默认只会绑定 public properties。在你的例子中 MyClass.MyList 是一个 字段 。要使绑定生效,您必须将其更改为 属性

如果您 wanted/needed 绑定非 public 属性,您可以传递一个 Action<BinderOptions>:

// manually
var opts = new MyClass();
var config = Configuration.GetSection("MyClass");
// bind manually
config.Bind(opts, o => o.BindNonPublicProperties = true);

// DI/services 
var config = Configuration.GetSection("MyClass");
services.Configure<MyClass>(config, o => o.BindNonPublicProperties = true);

即使 BinderOptions 仍然无法绑定到字段。另请注意,集合 接口 、数组和仅 get 属性等事物的行为各不相同。您可能需要稍微尝试一下,以确保按照您的意愿进行绑定。

如果您appsettings.json喜欢:

{ 
  "SomeConfig": {
  "Key1": "Value1",
  "Key2": "Value2",
  "Key3": "Value3"
  } 
} 

然后您可以将 POCO 设置为:

public struct SomeConfig
{
    public string Key1 { get; set; }

    public string Key2 { get; set; }

    public string Key3 { get; set; }
}

在此之后你需要把 services.Configure<SomeConfig>(Configuration.GetSection("SomeConfig"));条目 在 public void ConfigureServices(IServiceCollection services)

现在在任何 class 你想使用它的地方:

private readonly ILogger logger;
private readonly SomeConfig someConfigurations;

public SampleService(IOptions<SomeConfig> someConfigOptions, ILogger logger)
{
   this.logger = logger;
   someConfigurations = someConfigOptions.Value;
   logger.Information($"Value of key1 : '{someConfigurations.Key1}'");
}