【问题标题】:How to parse json settings in appsettings.json into a class in c# .netcore如何将 appsettings.json 中的 json 设置解析为 c# .net core 中的类
【发布时间】:2020-11-19 15:15:11
【问题描述】:

我有一个看起来像这样的 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&lt;MyModel&gt; 时,我得到的只是空值。我哪里错了?

【问题讨论】:

  • 您能否分享您将 json 转换为模型的代码?否则,您可能必须使用 Newtonsoft JSON 将其读入对象中。
  • @Slipoch 这就是我要问的问题。如何通过此配置魔术直接将 JSON 转换为“MyModel”?
  • 您所描述的应该可以工作(配置 + IOptions)。如果您想验证它是否正确绑定,您可以使用var o = new MyModel(); Configuration.GetSection("MyModel").Bind(o);,然后检查现在应该填充的o。如果您还没有通过传递引用获得 Microsoft.Extensions.Configuration.Binder 的引用,则可能需要它。
  • 虽然现在更仔细地查看您的课程,但MyList 是一个字段。活页夹仅适用于 properties,因此请添加 { get; set; },您应该一切顺利
  • @pinkfloydx33 哇,这是有史以来最大的问题。谢谢!

标签: c# .net-core configuration app-config configurationsection


【解决方案1】:

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

确定绑定到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 是一个字段。要使绑定生效,您必须改为将其更改为 属性

如果您想要/需要绑定非public 属性,您可以传递Action&lt;BinderOptions&gt;

// 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 仅属性之类的行为会有所不同。您可能需要尝试一下,以确保事情符合您的预期。

【讨论】:

    【解决方案2】:

    如果你有一些 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&lt;SomeConfig&gt;(Configuration.GetSection("SomeConfig")); 条目 在public void ConfigureServices(IServiceCollection services)

    现在在任何你想使用它的类中:

    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}'");
    }
    

    【讨论】:

      猜你喜欢
      • 2021-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      相关资源
      最近更新 更多