.NET Core configuration manager, reading a dictionary where one key has a colon inside, gives an odd error message about the value, is this expected?

邮差的信 提交于 2019-12-13 02:39:43

问题


The following program:

using System;
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;

namespace ConsoleApp3
{
    class Program
    {
        static void Main()
        {
            var builder = new ConfigurationBuilder();
            builder.AddJsonFile("appsettings.json");

            var configuration = builder.Build();
            var options = configuration.Get<Options>();
            foreach (var kvp in options.Values)
                Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
    }

    internal class Options
    {
        public Dictionary<string, bool> Values { get; } = new Dictionary<string, bool>();
    }
}

When given this appsettings.json file, runs perfectly:

{
    "Values": {
        "a": true,
        "b": false
    }
}

but change the appsettings.json contents to this:

{
    "Values": {
        "a:b": true,
        "b": false
    }
}

and I get this exception:

Unhandled Exception: System.InvalidOperationException: Cannot create instance of type 'System.Boolean' because it is missing a public parameterless constructor.

stack trace:

   at Microsoft.Extensions.Configuration.ConfigurationBinder.CreateInstance(Type type)
   at Microsoft.Extensions.Configuration.ConfigurationBinder.BindInstance(Type type, Object instance, IConfiguration config, BinderOptions options)
   at Microsoft.Extensions.Configuration.ConfigurationBinder.BindDictionary(Object dictionary, Type dictionaryType, IConfiguration config, BinderOptions options)
   at Microsoft.Extensions.Configuration.ConfigurationBinder.BindInstance(Type type, Object instance, IConfiguration config, BinderOptions options)
   at Microsoft.Extensions.Configuration.ConfigurationBinder.BindProperty(PropertyInfo property, Object instance, IConfiguration config, BinderOptions options)
   at Microsoft.Extensions.Configuration.ConfigurationBinder.BindNonScalar(IConfiguration configuration, Object instance, BinderOptions options)
   at Microsoft.Extensions.Configuration.ConfigurationBinder.BindInstance(Type type, Object instance, IConfiguration config, BinderOptions options)
   at Microsoft.Extensions.Configuration.ConfigurationBinder.Get[T](IConfiguration configuration, Action`1 configureOptions)
   at ConsoleApp3.Program.Main() in D:\Dev\ConsoleApp3\ConsoleApp3\Program.cs:line 15

What am I doing wrong? Note that having a colon in the key is perfectly legal json, but perhaps storing any odd dictionary in the appsettings.json file is not supported?


回答1:


Reference Configuration in ASP.NET Core: Hierarchical configuration data

The Configuration API is capable of maintaining hierarchical configuration data by flattening the hierarchical data with the use of a delimiter in the configuration keys.

When the file is read into configuration, unique keys are created to maintain the original hierarchical data structure of the configuration source. The sections and keys are flattened with the use of a colon (:) to maintain the original structure

That means that in the following appsettings.json file

{
    "Values": {
        "a:b": true,
        "b": false
    }
}

The keys would be flattened to

  • Values:a:b
  • Values:b

which is going to break the structure of settings file when the ConfigurationBinder.BindDictionary tries to bind the Dictionary<string, bool> property in the Options

Also referencing this GitHub Issue

Colons are reserved for special meaning in the keys, so they shouldn't be used as part of normal key values.



来源:https://stackoverflow.com/questions/52121374/net-core-configuration-manager-reading-a-dictionary-where-one-key-has-a-colon

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!