2009-01-15 16 views
10

Estoy tratando de implementar una forma genérica para leer las 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.Método genérico para leer secciones de configuració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 he intentado 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 solamente de valores clave

  • es una implementación de tales ¿posible? 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 de bienvenida.

Gracias.

Respuesta

9

Desde archivo de configuración es archivo XML, puede utilizar las 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 toda {clave, valor} pareja 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.

2

¿Lees tu configuración en un XmlDocument y luego utilizas XPath para encontrar los elementos que buscas?

Algo así 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) 

...

1

Cuando ha especificado NameValueSectionHandler como el atributo de tipo para una sección y llama al Configuration.GetSection(string), recibirá una instancia DefaultSection como tipo de devolución.

string SectionInformation.SectionInformation.GetRawXml() es la clave en este caso para entrar en sus datos.

Respondí otra pregunta similar con una forma válida de hacerlo utilizando System.Configuration que puede consultar para obtener todos los detalles y un fragmento de código. NameValueSectionHandler can i use this section type for writing back to the app

2

Usted 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); 
+0

Esto funcionó muy bien! – codechurn

Cuestiones relacionadas