Config.NET 是否允许将 JSON 对象解析为字典?

问题描述 投票:0回答:1

根据 Config.NET 文档,JSON array (

[]
) 可以解析为 IEnumerable:

许多提供程序不支持嵌套结构。假设您有以下配置声明:

//collection element
public interface IArrayElement
{
string Username { get; }

string Password { get; }
}

//top level configuration
public interface IConfig
{
IEnumerable<IArrayElement> Creds { get; }
}

并且您想传递两个在 json 中表示如下的元素:

"Creds": [
   {
      "Username": "user1",
      "Password": "pass1"
   },
   {
      "Username": "user2",
      "Password":  "pass2"
   }
]

但是 JSON object (

{}
) 又如何呢?是否可以将对象类似地解析为字典结构?就我而言,我正在尝试解析一组颜色。下面的“Colors”对象是否可以解析为一个
System.Collections.Generic.IDictionary<string, IEnumerable<int>>
,其中键是颜色的名称(
string
)?

// JSON
"ApplicationConfiguration": {
   "Palette": {
     "DefaultLineThickness": 4,
     "DefaultTextSize": 30,
     "Colors": {
       "Red": [ 255, 0, 0 ],
       "Green": [ 50, 205, 50 ],
       "Blue": [ 65, 105, 225 ]
     },
   ...
}

我想我可以指定一个颜色名称数组 (

IEnumerable<string>
) 和相应的 RGB 值数组 (
IEnumerable<IEnumerable<int>>
)(如果可能的话)。或者,我可以创建一个包含名称和值属性的 ColourConfiguration 类,名称为
string
,值为
IEnumerable<int>
。然而,如果 JSON 对象可以直接解析为字典,那么对于开发人员和用户来说都会容易得多。这就是这个问题的动机。

我在上面的 JSON 上尝试了以下接口,但没有成功。尝试访问

System.NotSupportedException
属性时会抛出
Colors

public interface IApplicationConfiguration
{
    public interface IPaletteConfiguration
    {
        [Option(DefaultValue = 4)]
        public int DefaultLineThickness { get; set; }

        [Option(DefaultValue = 30)]
        public int DefaultTextSize { get; set; }

        public IDictionary<string, IEnumerable<int>> Colors { get; set; }
    }

    public IPaletteConfiguration Palette { get; set; }
}
c# config
1个回答
0
投票

虽然这在标准序列化中有效,但在 Config.Net 中不受支持

收藏
Config.Net 支持原始类型和接口的集合。
集合必须始终声明为 IEnumerable 并且只有一个 getter。
目前集合是只读的,在未来的版本中可能会支持写入集合。

所以我们不能直接使用

IDictionary<>
,我们只能使用它的IEnumerable定义:
IEnumerable<KeyValuePair<TKey, TValue>>
但是
KeyValuePair<TKey, TValue>
本身不被支持,即使你将JSON更改为字符串类型键和值对的数组:

"ColorsThatDontWork": [
      { "Red": "255, 0, 0 " },
      { "Green": " 50, 205, 50 " } ,
      { "Blue": " 65, 105, 225 " }
    ]
 'settings.ApplicationConfiguration.Palette' threw an exception of type 'System.NotSupportedException'
    Data: {System.Collections.ListDictionaryInternal}
    HResult: -2146233067
    HelpLink: null
    InnerException: null
    Message: "type System.Collections.Generic.KeyValuePair`2[System.String,System.String] on object 'ColorsThatDontWork' is not supported."
    Source: "Config.Net"
    StackTrace: "   at Config.Net.Core.Box.BoxFactory.ValidateSupportedType(ResultBox rb, ValueHandler valueHandler)\r\n   at Config.Net.Core.Box.BoxFactory.DiscoverProperties(Type t, ValueHandler valueHandler, Dictionary`2 result, String basePath)\r\n   at Config.Net.Core.Box.BoxFactory.Discover(Type t, ValueHandler valueHandler, String basePath)\r\n   at Config.Net.Core.InterfaceInterceptor..ctor(Type interfaceType, IoHandler ioHandler, String prefix)\r\n   at Config.Net.Core.Box.ProxyResultBox.InitialiseAt(Int32 index, IoHandler ioHandler, String prefix)\r\n   at Config.Net.Core.DynamicReader.ReadProxy(ProxyResultBox xbox, Int32 index)\r\n   at Config.Net.Core.DynamicReader.Read(ResultBox rbox, Int32 index, Object[] arguments)\r\n   at Config.Net.Core.InterfaceInterceptor.Intercept(IInvocation invocation)\r\n   at Castle.DynamicProxy.AbstractInvocation.Proceed()\r\n   at Castle.Proxies.IApplicationConfigurationProxy.get_Palette()"
    TargetSite: {Void ValidateSupportedType(Config.Net.Core.Box.ResultBox, Config.Net.Core.ValueHandler)}

在我们担心嵌套

IEnumerable<int>
作为字典的 value 的预期类型参数之前,Config.Net 甚至不支持将字符串属性的 JSON 对象结构读取到字典中。

如果您的配置中需要这些结构,那么可能是时候开始使用 .Net Core 中的标准选项绑定了:.NET 中的选项模式

Config.Net 不再是一个活跃的项目,但是您可以尝试在项目存储库上发布问题:https://github.com/aloneguid/config

它解决了 .Net Framework 中的一个问题,但 .Net Core 专门提供了一个新的解决方案来管理应用程序配置,该解决方案确实适合您的场景,因此值得研究一下采用它可能需要付出多少努力,或者您是否陷入困境在 .net 框架中,您仍然可以使用 JSON.Net 反序列化您的 JSON 设置。

© www.soinside.com 2019 - 2024. All rights reserved.