.NET Core 使用配置绑定到带数组的选项 [英] .NET Core use Configuration to bind to Options with Array

查看:25
本文介绍了.NET Core 使用配置绑定到带数组的选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 .NET Core Microsoft.Extensions.Configuration 是否可以将 Configuration 绑定到包含数组的对象?

ConfigurationBinder 有一个方法 BindArray,所以我认为它会起作用.

但是当我尝试它时,我得到了一个例外:

<块引用>

System.NotSupportedException: ArrayConverter 无法从 System.String 转换.

这是我的精简代码:

公共类测试{私有类 ExampleOption{公共 int[] 数组 {get;set;}}[测试]公共无效 CanBindArray(){//安排变量配置 =新的配置构建器().AddInMemoryCollection(new List>{new KeyValuePair("数组", "[1,2,3]")}).建造();var exampleOption= new ExampleOption();//行为config.Bind(complexOptions);//抛出异常//断言exampleOption.ShouldContain(1);}}

解决方案

错误在您的输入定义中.该示例将键Array"设置为字符串值[1,2,3]"(在基于 C# 的 InMemoryCollection 中)并假设它是解析的 JSON 样式.那是错的.它只是没有被解析.

配置系统中数组值的编码约定是通过在其后面重复一个冒号和一个索引的键.以下示例按您的意图工作:

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

如果使用 JSON 文件,也会发生冒号键重复方案(此处通过对 AddJsonFile 的额外调用)...

<代码>{"mySecondArray": [1, 2, 3]}

生成的组合配置将包含遵循与上述内存使用相同模式的键:

计数 = 8[0]: {[mySecondArray, ]}[1]: {[mySecondArray:2, 3]}[2]: {[mySecondArray:1, 2]}[3]: {[mySecondArray:0, 1]}[4]:{[数组,]}[5]: {[数组:2, 3]}[6]: {[数组:1, 2]}[7]:{[数组:0, 1]}

配置系统与 JSON/INI/XML/... 等存储格式无关,本质上只是一个 string->string 字典,带有冒号构成一个层次结构键内.>

绑定然后能够通过约定解释一些层次结构,因此也绑定数组、集合、对象和字典.有趣的是,对于数组,它并不关心冒号后面的数字,而只关心 迭代 配置部分的子项(此处为数组")并获取子项的值.再次对孩子进行排序,考虑数字但也将字符串排序作为第二个选项(OrdinalIgnoreCase).

Using the .NET Core Microsoft.Extensions.Configuration is it possible to bind to a Configuration to an object that contains an array?

ConfigurationBinder has a method BindArray, so I'd assume it would work.

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. 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) ...

{
  "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.

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).

这篇关于.NET Core 使用配置绑定到带数组的选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆