根据 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; }
}
虽然这在标准序列化中有效,但在 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 设置。