Общий метод для чтения разделов конфигурации - PullRequest
10 голосов
/ 15 января 2009

Я пытаюсь реализовать универсальный способ чтения разделов из файла конфигурации. Файл конфигурации может содержать «стандартные» разделы или «пользовательские» разделы, как показано ниже.

<configuration> 
<configSections>
    <section name="NoteSettings" type="System.Configuration.NameValueSectionHandler"/>
</configSections>   
<appSettings>
    <add key="AutoStart" value="true"/>
    <add key="Font" value="Verdana"/>
</appSettings>  
<NoteSettings>
    <add key="Height" value="100"/>
    <add key="Width" value="200"/>
</NoteSettings> 

Метод, который я попробовал, выглядит следующим образом:

    private string ReadAllSections()
    {
        StringBuilder configSettings = new StringBuilder();

        Configuration configFile = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);

        foreach (ConfigurationSection section in configFile.Sections)
        {
            configSettings.Append(section.SectionInformation.Name);
            configSettings.Append(Environment.NewLine);                

            if (section.GetType() == typeof(DefaultSection))
            {
                NameValueCollection sectionSettings = ConfigurationManager.GetSection(section.SectionInformation.Name) as NameValueCollection;

                if (sectionSettings != null)
                {
                    foreach (string key in sectionSettings)
                    {
                        configSettings.Append(key);
                        configSettings.Append(" : ");
                        configSettings.Append(sectionSettings[key]);
                        configSettings.Append(Environment.NewLine);
                    }
                }
            }

            configSettings.Append(Environment.NewLine);
        }

        return configSettings.ToString();
    }

При условии, что все пользовательские разделы будут иметь только КЛЮЧЕВОЕ ЗНАЧЕНИЕ

  • Возможна ли такая реализация? И если да, есть ли «более чистое» и более элегантное решение, чем это?
  • Вышеуказанный метод также читает «невидимые» разделы, такие как mscorlib, system.diagnostics . Этого можно избежать?
  • System.Data.Dataset возвращает набор данных, который не может быть приведен к коллекции NameValueCollection. Как это можно сделать?

Исправления / предложения приветствуются.

Спасибо.

Ответы [ 4 ]

9 голосов
/ 15 января 2009

Поскольку файл конфигурации является файлом XML, вы можете использовать XPath-запросы для этой задачи:

    Configuration configFile = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
    XmlDocument document = new XmlDocument();
    document.Load(configFile.FilePath);
    foreach (XmlNode node in document.SelectNodes("//add"))
    {
        string key = node.SelectSingleNode("@key").Value;
        string value = node.SelectSingleNode("@value").Value;
        Console.WriteLine("{0} = {1}", key, value);
    }

Если вам нужно получить все пары {ключ, значение}, вам нужно определить триплеты запросов XPath: 1 - основной запрос для выбора узлов с аналогичной структурой. 2, 3 - запросы на извлечение узлов ключа и значения из узлов, полученных по первому запросу. В вашем случае достаточно иметь общий запрос для всех узлов, но легко поддерживать поддержку различных пользовательских разделов.

2 голосов
/ 15 марта 2011

Пользовательский раздел можно прочитать следующим образом:

var sectionInformation = configuration.GetSection("mysection").SectionInformation;
var xml = sectionInformation.GetRawXml();
var doc = new XmlDocument();
doc.LoadXml(xml);
IConfigurationSectionHandler handler = (IConfigurationSectionHandler)Type.GetType(sectionInformation.Type).GetConstructor(new Type[0]).Invoke(new object[0]);
var result = handler.Create(null, null, doc.DocumentElement);
2 голосов
/ 15 января 2009

Считайте вашу конфигурацию в XmlDocument, а затем используйте XPath, чтобы найти элементы, которые вы ищете?

Что-то вроде;

XmlDocument doc = new XmlDocument();
doc.Load(HttpContext.Current.Server.MapPath("~/web.config"));

XmlNodeList list = doc.SelectNodes("//configuration/appSettings");

foreach (XmlNode node in list[0].ChildNodes)

...

1 голос
/ 03 февраля 2010

Если вы указали NameValueSectionHandler в качестве атрибута типа для раздела и вызвали Configuration.GetSection(string), вы получите экземпляр DefaultSection в качестве возвращаемого типа.

string SectionInformation.SectionInformation.GetRawXml() - ключ в этом случае для доступа к вашим данным.

Я ответил на другой похожий вопрос с правильным способом сделать это, используя System.Configuration, на который можно сослаться, чтобы получить все детали и фрагмент кода. NameValueSectionHandler могу ли я использовать этот тип раздела для обратной записи в приложение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...