使用ConfigurationManager.OpenMappedExeConfiguration时,如何从ConfigSection中获取定义为NameValueSectionHandler的值

JJS*_*JJS 5 .net configuration configurationmanager

当您使用应用程序的当前配置文件时,从使用System.Configuration.NameValueSectionHandler定义的部分的配置文件中获取值很容易.

示例配置文件.

<configuration>
  <configSections>
    <section name="MyParams" type="System.Configuration.NameValueSectionHandler" />
  </configSections>

  <MyParams>
    <add key="FirstParam" value="One"/>
    <add key="SecondParam" value="Two"/>
  </MyParams>
</configuration>
Run Code Online (Sandbox Code Playgroud)

示例代码,可以轻松读取它.

NameValueCollection myParamsCollection =
   ConfigurationManager.GetSection("MyParams") as NameValueCollection;
Run Code Online (Sandbox Code Playgroud)

这是不起作用的代码.

NameValueCollection collection =
  ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
  .GetSection("MyParams") as NameValueCollection;
Run Code Online (Sandbox Code Playgroud)

在编译时失败并出现以下错误.

无法通过引用转换,装箱转换,拆箱转换,换行转换或空类型转换将类型'System.Configuration.ConfigurationSection'转换为'System.Collections.Specialized.NameValueCollection'.

ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)返回System.Configuration.Configuration,Configuration.GetSection返回ConfigurationSection.

ConfigurationManager.GetSection返回对象.

那么,当我必须使用OpenExeConfiguration时,如何取回我的NameValueCollection?

JJS*_*JJS 10

两年前我碰到了自己的答案.

NameValueSectionHandler - 我可以使用此节类型写回应用程序配置文件吗?

这是我解决当前问题的方法.

ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap() { 
   ExeConfigFilename = "path to config here" 
    };

Configuration config = ConfigurationManager.OpenMappedExeConfiguration(
   configFileMap, ConfigurationUserLevel.None);

ConfigurationSection myParamsSection = config.GetSection("MyParams");

string myParamsSectionRawXml = myParamsSection .SectionInformation.GetRawXml();
XmlDocument sectionXmlDoc = new XmlDocument();
sectionXmlDoc.Load(new StringReader(myParamsSectionRawXml ));
NameValueSectionHandler handler = new NameValueSectionHandler();

NameValueCollection handlerCreatedCollection = 
   handler.Create(null, null, sectionXmlDoc.DocumentElement) as NameValueCollection;

Console.WriteLine(handlerCreatedCollection.Count);
Run Code Online (Sandbox Code Playgroud)

一种适用于任何旧版IConfigurationSectionHandler类型NameValueSectionHandler,DictionarySectionHandler,SingleTagSectionHandler的方法.

public static object GetConfigurationValues(string configFileName, string sectionName)
{
    ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap() { ExeConfigFilename = configFileName };
    Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
    ConfigurationSection section = config.GetSection(sectionName);
    string xml = section.SectionInformation.GetRawXml();
    XmlDocument doc = new XmlDocument();
    doc.Load(XmlReader.Create(new StringReader(xml)));
    string type = section.SectionInformation.Type;
    string assemblyName = typeof(IConfigurationSectionHandler).Assembly.GetName().FullName;
    ObjectHandle configSectionHandlerHandle = Activator.CreateInstance(assemblyName, section.SectionInformation.Type);
    if (configSectionHandlerHandle != null)
    {
        IConfigurationSectionHandler handler = configSectionHandlerHandle.Unwrap() as IConfigurationSectionHandler;
        return handler.Create(null, null, doc.DocumentElement);
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

  • 不客气@tsilb。我不知道这是否是“正确的方法”。当如此黑暗的咒语被公开时,我担心凡人的灵魂。至少这不会复活亡灵。至少我认为不会... (2认同)