自定义App.config NameValueSectionHandler的bug修复创建自己的NameValueCollectionSectionHandler
在很多时候我们需要自定义我们自己的自定义App.config 文件,而微软为我们提供了默认的
System.Configuration.NameValueSectionHandler
System.Configuration.DictionarySectionHandler
System.Configuration.SingleTagSectionHandler
经常用这些也没有出现问题。今天因项目需求的问题再次使用System.Configuration.NameValueSectionHandler,相应的配置如下:
<configSections> <section name= "mySection1" type= "System.Configuration.NameValueSectionHandler, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> </configSections> <mySection1> <add key= "filepath" value= "Views/Channel/men" ></add> <add key= "filepath" value= "Views/Channel/homme" ></add> <add key= "filepath" value= "Views/Channel/fleece/20120906" ></add> <add key= "filepath" value= "Views/Channel/Designer" ></add> <add key= "filepath" value= "Views/Channel/coats/20120816" ></add> <add key= "filepath" value= "Views/Channel/xiuxianku/20120517" ></add> <add key= "filepath" value= "men" ></add> <add key= "filepath" value= "homme" ></add> <add key= "filepath" value= "fleece" ></add> <add key= "filepath" value= "Designer" ></add> <add key= "filepath" value= "coats" ></add> <add key= "filepath" value= "xiuxianku" ></add> </mySection1> |
然后在读取相应的配置信息。
NameValueCollection mySection1 = ((NameValueCollection)ConfigurationManager.GetSection( "mySection1" )); List< string > fileList = mySection1[ "filepath" ].Split( new char [] { ',' }).ToList(); |
得到的结果只有最后一条,而我们所用的NameValueCollection不一致,让我们来看看源码吧:
internal static object CreateStatic( object parent, XmlNode section, string keyAttriuteName, string valueAttributeName) { ReadOnlyNameValueCollection values; if (parent == null ) { values = new ReadOnlyNameValueCollection(StringComparer.OrdinalIgnoreCase); } else { ReadOnlyNameValueCollection values2 = (ReadOnlyNameValueCollection) parent; values = new ReadOnlyNameValueCollection(values2); } HandlerBase.CheckForUnrecognizedAttributes(section); foreach (XmlNode node in section.ChildNodes) { if (!HandlerBase.IsIgnorableAlsoCheckForNonElement(node)) { if (node.Name == "add" ) { string str = HandlerBase.RemoveRequiredAttribute(node, keyAttriuteName); string str2 = HandlerBase.RemoveRequiredAttribute(node, valueAttributeName, true ); HandlerBase.CheckForUnrecognizedAttributes(node); values[str] = str2; } else if (node.Name == "remove" ) { string name = HandlerBase.RemoveRequiredAttribute(node, keyAttriuteName); HandlerBase.CheckForUnrecognizedAttributes(node); values.Remove(name); } else if (node.Name.Equals( "clear" )) { HandlerBase.CheckForUnrecognizedAttributes(node); values.Clear(); } else { HandlerBase.ThrowUnrecognizedElement(node); } } } values.SetReadOnly(); return values; } |
很明显在add的时候它用的是values[str] = str2;而不是调用add方法。
修改后代码:
public class NameValueCollectionSectionHandler : IConfigurationSectionHandler { // Fields private const string defaultKeyAttribute = "key"; private const string defaultValueAttribute = "value"; // Methods public object Create(object parent, object context, XmlNode section) { return CreateStatic(parent, section, this.KeyAttributeName, this.ValueAttributeName); } internal static object CreateStatic(object parent, XmlNode section) { return CreateStatic(parent, section, "key", "value"); } internal static object CreateStatic(object parent, XmlNode section, string keyAttriuteName, string valueAttributeName) { NameValueCollection values; if (parent == null) { values = new NameValueCollection(StringComparer.OrdinalIgnoreCase); } else { NameValueCollection values2 = (NameValueCollection)parent; values = new NameValueCollection(values2); } foreach (XmlNode node in section.ChildNodes) { if (node.Name == "add") { string key = node.Attributes[keyAttriuteName].Value; string value = node.Attributes[valueAttributeName].Value; values.Add(key, value); } else if (node.Name == "remove") { string key = node.Attributes[keyAttriuteName].Value; values.Remove(key); } else if (node.Name.Equals("clear")) { values.Clear(); } } return values; } // Properties protected virtual string KeyAttributeName { get { return "key"; } } protected virtual string ValueAttributeName { get { return "value"; } } }
当然这样运行结果就和我们常用的NameValueCollection一样。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构