Общий метод чтения разделов конфигурации
Я пытаюсь реализовать общий способ чтения разделов из файла конфигурации. Конфигурационный файл может содержать "стандартные" разделы или "пользовательские" разделы, как показано ниже.
<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();
}
Предполагая, что все пользовательские разделы будут иметь только KEY-VALUE
- Возможно ли такая реализация? И если да, есть ли "более чистое" и более элегантное решение, чем этот?
- Вышеуказанный метод также читает "невидимые" разделы, такие как mscorlib, system.diagnostics. Можно ли этого избежать?
- System.Data.Dataset возвращает набор данных, который не может быть передан в NameValueCollection. Как это можно обрабатывать?
Исправления/предложения приветствуются.
Спасибо.
Ответы
Ответ 1
Так как файл конфигурации является 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
Прочитайте свою конфигурацию в 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)
...
Ответ 3
Вы можете прочитать пользовательский раздел следующим образом:
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);
Ответ 4
Если вы указали NameValueSectionHandler
как атрибут типа для раздела и вызвали на Configuration.GetSection(string)
, вы получите экземпляр DefaultSection
в качестве возвращаемого типа.
string SectionInformation.SectionInformation.GetRawXml()
- это ключ в этом случае, чтобы попасть в ваши данные.
Я ответил на другой подобный вопрос с допустимым способом сделать это, используя System.Configuration
, с которым вы можете ссылаться, чтобы получить все детали и фрагмент кода.
NameValueSectionHandler можно использовать этот тип раздела для записи в приложение