c# - cref - Método genérico para leer secciones de configuración
remarks c# (4)
¿Lees tu configuración en un XmlDocument y luego utilizas XPath para encontrar los elementos que buscas?
Algo como;
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)
...
Estoy tratando de implementar una forma genérica para leer secciones de un archivo de configuración. El archivo de configuración puede contener secciones ''estándar'' o secciones ''personalizadas'' como se muestra a continuación.
<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>
El método que probé es el siguiente:
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();
}
Suponiendo que todas las secciones personalizadas tendrán solo KEY-VALUE
- ¿Es posible tal implementación? Y si es así, ¿hay una solución más "limpia" y más elegante que esta?
- El método anterior también lee secciones ''invisibles'' como mscorlib, system.diagnostics . ¿Esto es evitable?
- System.Data.Dataset devuelve un conjunto de datos que no se pudo convertir a NameValueCollection. ¿Cómo se puede manejar esto?
Correcciones / sugerencias bienvenidas.
Gracias.
Como el archivo de configuración es un archivo XML, puede usar consultas XPath para esta tarea:
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);
}
Si necesita obtener todos los pares {clave, valor}, entonces necesita definir trillizos de consultas XPath: 1 - consulta principal para seleccionar nodos con estructura similar. 2, 3 - consultas para extraer nodos clave y de valor de los nodos recuperados por la primera consulta. En su caso, es suficiente tener consultas comunes para todos los nodos, pero es fácil mantener el soporte para diferentes secciones personalizadas.
Puede leer una sección personalizada de la siguiente manera:
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);
Cuando haya especificado NameValueSectionHandler
como el atributo de tipo para una sección y llame a Configuration.GetSection(string)
, recibirá una instancia DefaultSection
como tipo de devolución.
string SectionInformation.SectionInformation.GetRawXml()
es la clave en este caso para acceder a sus datos.
Respondí otra pregunta similar con una forma válida de hacerlo mediante System.Configuration
que puede consultar para obtener todos los detalles y un fragmento de código. NameValueSectionHandler puedo usar este tipo de sección para volver a escribir en la aplicación