简体   繁体   English

.NET Core 使用配置绑定到带数组的选项

[英].NET Core use Configuration to bind to Options with Array

Using the .NET Core Microsoft.Extensions.Configuration is it possible to bind to a Configuration to an object that contains an array?使用 .NET Core Microsoft.Extensions.Configuration是否可以将 Configuration 绑定到包含数组的对象?

ConfigurationBinder has a method BindArray , so I'd assume it would work. ConfigurationBinder有一个BindArray方法,所以我认为它会起作用。

But when I try it out I get an exception:但是当我尝试时,我得到了一个例外:

System.NotSupportedException: ArrayConverter cannot convert from System.String.

Here's my slimmed down code:这是我的精简代码:

public class Test
{
   private class ExampleOption
   { 
      public int[] Array {get;set;}
   }

   [Test]
   public void CanBindArray()
   {
       // ARRANGE
       var config =
            new ConfigurationBuilder()
            .AddInMemoryCollection(new List<KeyValuePair<string, string>>
            {
                new KeyValuePair<string, string>("Array", "[1,2,3]")
            })
            .Build();

        var exampleOption= new ExampleOption();

        // ACT
        config.Bind(complexOptions); // throws exception

       // ASSERT
       exampleOption.ShouldContain(1);
   }
}

The error is in your input definition.错误在您的输入定义中。 The sample sets a key "Array" to a string value of "[1,2,3]" (in the C# based InMemoryCollection) and makes the assumption it is parsed JSON style.该示例将键“Array”设置为字符串值“[1,2,3]”(在基于 C# 的 InMemoryCollection 中),并假设它是解析的 JSON 样式。 That is wrong.那是错误的。 It is just not parsed.它只是没有被解析。

The encoding convention of array values in the config system is by repeating the key with a colon and an index behind it.配置系统中数组值的编码约定是通过用冒号和后面的索引重复键。 The following sample works like you intend to do:以下示例的工作方式与您打算做的一样:

var config = new ConfigurationBuilder()
        .AddInMemoryCollection(new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("Array:0", "1"),
            new KeyValuePair<string, string>("Array:1", "2"),
            new KeyValuePair<string, string>("Array:2", "3")
        })
        .Build();

The colon-key-repeating scheme happens also if JSON file is used (here by an additional call to AddJsonFile) ...如果使用 JSON 文件(此处通过对 AddJsonFile 的附加调用),也会发生冒号键重复方案......

{
  "mySecondArray":  [1, 2, 3]
}

the resulting combined configuration will contain the keys which follow the same pattern as illustrated for in-memory usage above:生成的组合配置将包含遵循与上述内存使用相同模式的键:

Count = 8
[0]: {[mySecondArray, ]}
[1]: {[mySecondArray:2, 3]}
[2]: {[mySecondArray:1, 2]}
[3]: {[mySecondArray:0, 1]}
[4]: {[Array, ]}
[5]: {[Array:2, 3]}
[6]: {[Array:1, 2]}
[7]: {[Array:0, 1]}

The config system is agnostic to storage formats like JSON/INI/XML/... and is essentially just a string->string dictionary with colon making up a hierarchy within the key .配置系统与 JSON/INI/XML/... 等存储格式无关,本质上只是一个 string->string 字典,其中冒号在 key 内构成层次结构。

Bind is then able to interpret some of the hierarchy by conventions and therefore binds also arrays, collections, objects and dictionaries.然后绑定能够通过约定解释一些层次结构,因此也绑定数组、集合、对象和字典。 Interestingly for arrays, it does not care about the numbers behind the colon but just iterate the children of the configuration section (here "Array") and take the values of the children.有趣的是,对于数组,它并不关心冒号后面的数字,而只是迭代配置部分的子项(此处为“数组”)并获取子项的值。 The sorting of the children again, takes the numbers into consideration but also sorts strings as a second option (OrdinalIgnoreCase).分拣再次孩子,需要的数量考虑,而且排序字符串作为第二个选项(OrdinalIgnoreCase)。

With recent additions to C# language it is cleaner to use the newer syntax:随着最近对 C# 语言的添加,使用更新的语法更清晰:

var config = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string>
    {
        { "Array:0", "1" },
        { "Array:1", "2" },
        { "Array:2", "3" },
    })
    .Build();

You can configure ExampleOption with code in ConfigureServices method:您可以使用ConfigureServices方法中的代码配置ExampleOption

 public void ConfigureServices(IServiceCollection services)
 {
      services.Configure<ExampleOption>(myOptions =>
      {
          myOptions.Array = new int[] { 1, 2, 3 };
      });
 }

or if you want to use json configuration file或者如果你想使用 json 配置文件

appsettings.json : appsettings.json

{
  "ExampleOption": {
     "Array": [1,2,3]
  }
}

ConfigureServices : ConfigureServices

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

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

相关问题 如何将嵌套的 json 配置绑定到 .net 核心中的选项 - How to bind nested json configuration to options in .net core .net核心中的配置选项 - Configuration Options in .net core 如何将配置绑定到JSON对象.Net Core数组 - How to bind configuration to array of JSON Objects .Net Core 无法使用 Asp.Net Core 3 中的命名选项读取/绑定具有强类型 class 的配置设置 - Unable to read/bind configuration settings with strongly-typed class using Named Options in Asp.Net Core 3 如何从方法主体中提取配置选项并在 Dot Net Core 3.1 中使用配置 class - How to pull configuration options out of method body and use configuration class in Dot Net Core 3.1 在ASP.NET Core中访问配置选项:选项模式 - Accessing configuration options in ASP.NET Core: options pattern 如何在 .NET Core 3.1 中绑定新选项 object? - How do you bind a new options object in .NET Core 3.1? 是否可以将配置绑定到 .NET Core 中的无状态/只读模型? - Is it possible to bind configuration to stateless/readonly model in .NET Core? 为什么.NET Core选项的配置不适用于泛型类型参数? - Why does the configuration of .NET Core options not work with a generic type parameter? .net core 3.1 WorkerService 未加载配置选项/设置 - .net core 3.1 WorkerService not loading configuration options/settings
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM