2011-04-07 25 views
5

G'da a todo el mundo,elementos personalizados anidadas en app.config (C#)

Por horas que he estado tratando de averiguar cómo leer la configuración de app.config archivo:

<?xml version="1.0"?> 
<configuration> 

    <configSections> 
    <section name="Databases" type="McFix.DatabaseSection, McFix"/> 
    </configSections> 

    <Databases> 
    <Database name="database"> 
     <Tables> 
     <Table name="be_sessions"> 
      <Columns> 
      <Column name="sess_id"> 
      </Column> 
      </Columns> 
     </Table> 
     </Tables> 
    </Database> 
    </Databases> 

    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> 
    </startup> 
</configuration> 

El código para las clases controlador personalizado es here, también se copian a continuación:

public class DatabaseSection : ConfigurationSection 
{ 
    [ConfigurationProperty("Databases", IsDefaultCollection = false)] 
    public DatabaseInstanceCollection Databases 
    { 
     get { return (DatabaseInstanceCollection)this["Databases"]; } 
     set { this[""] = value; } 
    } 
} 
[ConfigurationCollection(typeof(DatabaseElement), AddItemName = "add", CollectionType = ConfigurationElementCollectionType.BasicMap)] 
public class DatabaseInstanceCollection : ConfigurationElementCollection 
{ 
    protected override ConfigurationElement CreateNewElement() 
    { 
     return new DatabaseElement(); 
    } 
    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((DatabaseElement)element).Name; 
    } 
} 
public class DatabaseElement : ConfigurationElement 
{ 
    [ConfigurationProperty("name", IsKey = true, IsRequired = true)] 
    public string Name 
    { 
     get { return (string)base["name"]; } 
     set { base["name"] = value; } 
    } 
} 

public class TableSection : ConfigurationSection 
{ 
    [ConfigurationProperty("Tables", IsDefaultCollection = true)] 
    public TableInstanceCollection Tables 
    { 
     get { return (TableInstanceCollection)this["Tables"]; } 
     set { this[""] = value; } 
    } 
} 

[ConfigurationCollection(typeof(TableElement), AddItemName = "Table", CollectionType = ConfigurationElementCollectionType.BasicMap)] 
public class TableInstanceCollection : ConfigurationElementCollection 
{ 
    protected override ConfigurationElement CreateNewElement() 
    { 
     return new TableElement(); 
    } 
    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((TableElement)element).Name; 
    } 
} 

public class TableElement : ConfigurationElement 
{ 
    [ConfigurationProperty("name", IsKey = true, IsRequired = true)] 
    public string Name 
    { 
     get { return (string)base["name"]; } 
     set { base["name"] = value; } 
    } 
} 

public class ColumnSection : ConfigurationSection 
{ 
    [ConfigurationProperty("Columns", IsDefaultCollection = true)] 
    public ColumnInstanceCollection Columns 
    { 
     get { return (ColumnInstanceCollection)this["Columns"]; } 
     set { this[""] = value; } 
    } 
} 

[ConfigurationCollection(typeof(ColumnElement), AddItemName = "Column", CollectionType = ConfigurationElementCollectionType.BasicMap)] 
public class ColumnInstanceCollection : ConfigurationElementCollection 
{ 
    protected override ConfigurationElement CreateNewElement() 
    { 
     return new ColumnElement(); 
    } 
    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((ColumnElement)element).Name; 
    } 
} 

public class ColumnElement : ConfigurationElement 
{ 
    [ConfigurationProperty("name", IsKey = true, IsRequired = true)] 
    public string Name 
    { 
     get { return (string)base["name"]; } 
     set { base["name"] = value; } 
    } 
} 

El problema es cuando intento de conseguir "Bases de datos" a través de la sección método GetSection:

Configuration Config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
DatabaseSection DbConfig = Config.GetSection("Databases") as DatabaseSection; 

programa lanza una ConfigurationErrorsException, la presentación de informes "elemento no reconocido 'Base de datos'", aunque sí que después de pasar por método get de DatabaseSection, a pesar de que defino AddItemName para DatabaseInstanceCollection como "base de datos". ¿Me falta algo, un atributo que permita que el código subyacente lea la aplicación.config correctamente?

+2

¿Qué pasa con el formato SO? Además, necesitarás hacer más trabajo para esto. Describe lo que no funcionó para ti y cuál es tu problema. Nadie va a leer tu código para descubrir qué salió mal. Dé ejemplos de sus fallas. –

+1

¿Estás preguntando cómo leer en la configuración de configuración con las clases que definiste? No vi nada en su código donde lo haya leído realmente. –

+0

Si desea publicar muestras de ** código, XML ** o ** datos **, resalte esas líneas en el editor de texto y haga clic en el "código". sample "button (' {} ') en la barra de herramientas del editor para formatear y sintaxis muy bien ¡Resaltarlo! SO ** ** formateará y mostrará muy bien si lo hace! –

Respuesta

7

enlaces obligatorios:

Después de un rápido vistazo parece que su problema es en esta línea:

[ConfigurationCollection(typeof(DatabaseElement), AddItemName = "add", CollectionType = ConfigurationElementCollectionType.BasicMap)] 

Esto indica que el archivo .config debería tener este aspecto:

<Databases> 
    <add><!-- Database goes here --></add> 
</Databases> 

es decir, su elemento Databases espera un hijo "agregar", para indicar que un artículo se debe agregar a la colección.

Usted debe tratar de cambiar la propiedad AddItemName de "añadir" a "base de datos":

[ConfigurationCollection(typeof(DatabaseElement), AddItemName = "Database", CollectionType = ConfigurationElementCollectionType.BasicMap)] 

(No he tenido la oportunidad de probar esto, puede haber otros problemas)

+0

Gracias Kragen, he buscado preguntas y respuestas para una configuración de aplicación similar para.NET aquí y visitó los enlaces que mencionó anteriormente, pero por desgracia. Intenté cambiar AddItemName a "Base de datos" pero tampoco me sirvió. Tengo la sospecha de que el elemento "Base de datos" debe declararse para la sección "Bases de datos", aunque pensé que se haría a través de la propiedad "AddItemName" del atributo ConfigurationCollection. –

+1

@ user696034 ¿Hace una diferencia el mensaje de error? También me di cuenta de que el elemento de configuración 'DatabaseElement' no hace referencia a la sección de configuración' TableSection', por lo que supongo que probablemente falle incluso después de resolver lo anterior. – Justin

+1

He logrado que todo funcione, pero tiene razón, Kragen, era necesario agregar TableInstanceCollection a DatabaseElement y ColumnInstanceCollection a TableElement. Además, la sección DatabaseSection tuvo que hacerse así para que funcione: –

1

Usted Correcto, Kragen, tuve que eliminar Table/ColumnSection y agregar Table/ColumnInstanceCollection a Database/TableElement. La propiedad 'Base de datos' de DatabaseSection debe ser similar a:

[ConfigurationProperty("", IsDefaultCollection = true)] 
     public DatabaseInstanceCollection Databases 
     { 
      get { return (DatabaseInstanceCollection)this[""]; } 
     } 
Cuestiones relacionadas