web-dev-qa-db-fra.com

Comment obtenir les valeurs d'une ConfigurationSection de type NameValueSectionHandler

Je travaille avec C #, Framework 3.5 (VS 2008).

J'utilise ConfigurationManager pour charger une configuration (et non le fichier app.config par défaut) dans un objet de configuration.

En utilisant la classe Configuration, j’ai pu obtenir un ConfigurationSection, mais je n’ai pas trouvé le moyen d’obtenir les valeurs de cette section.

Dans la configuration, le ConfigurationSection est de type System.Configuration.NameValueSectionHandler.

Pour ce que ça vaut, quand j'ai utilisé la méthode GetSection du ConfigurationManager (fonctionne seulement quand c'était sur mon fichier app.config par défaut), j'ai reçu un type d'objet, que je pouvais convertir en collection de paires de valeur-clé, et je viens de recevoir la valeur comme un dictionnaire. Cependant, je ne pouvais pas le faire lorsque j'ai reçu la classe ConfigurationSection de la classe Configuration.

EDIT: Exemple du fichier de configuration:

<configuration>
  <configSections>
    <section name="MyParams" 
             type="System.Configuration.NameValueSectionHandler" />
  </configSections>

  <MyParams>
    <add key="FirstParam" value="One"/>
    <add key="SecondParam" value="Two"/>
  </MyParams>
</configuration>

Exemple de la façon dont j'ai pu l'utiliser lorsqu'il était sur app.config (la méthode "GetSection" concerne uniquement le fichier app.config par défaut):

NameValueCollection myParamsCollection =
             (NameValueCollection)ConfigurationManager.GetSection("MyParams");

Console.WriteLine(myParamsCollection["FirstParam"]);
Console.WriteLine(myParamsCollection["SecondParam"]);
63
Liran B

Souffert de problème exact. Le problème était dû à NameValueSectionHandler dans le fichier .config. Vous devez utiliser AppSettingsSection à la place:

<configuration>

 <configSections>
    <section  name="DEV" type="System.Configuration.AppSettingsSection" />
    <section  name="TEST" type="System.Configuration.AppSettingsSection" />
 </configSections>

 <TEST>
    <add key="key" value="value1" />
 </TEST>

 <DEV>
    <add key="key" value="value2" />
 </DEV>

</configuration>

puis en code C #:

AppSettingsSection section = (AppSettingsSection)ConfigurationManager.GetSection("TEST");

btw NameValueSectionHandler n'est plus supporté dans la version 2.0.

21
nerijus

Voici un bon post qui montre comment le faire.

Si vous souhaitez lire les valeurs d'un fichier autre que app.config, vous devez le charger dans le ConfigurationManager.

Essayez cette méthode: ConfigurationManager.OpenMappedExeConfiguration ()

Il existe un exemple d'utilisation de cet article dans l'article MSDN.

17
MonkeyWrench

Essayez d’utiliser un AppSettingsSection au lieu d’un NameValueCollection. Quelque chose comme ça:

var section = (AppSettingsSection)config.GetSection(sectionName);
string results = section.Settings[key].Value;

Source: http://social.msdn.Microsoft.com/Forums/en-US/csharpgeneral/thread/d5079420-40cb-4255-9b3b-f9a41a1f7ad2/

13
Steven Ball

La seule façon pour que cela fonctionne est d'instancier manuellement le type de gestionnaire de section, de lui transmettre le code XML brut et de convertir l'objet résultant.

Cela semble plutôt inefficace, mais voilà.

J'ai écrit une méthode d'extension pour encapsuler ceci:

public static class ConfigurationSectionExtensions
{
    public static T GetAs<T>(this ConfigurationSection section)
    {
        var sectionInformation = section.SectionInformation;

        var sectionHandlerType = Type.GetType(sectionInformation.Type);
        if (sectionHandlerType == null)
        {
            throw new InvalidOperationException(string.Format("Unable to find section handler type '{0}'.", sectionInformation.Type));
        }

        IConfigurationSectionHandler sectionHandler;
        try
        {
            sectionHandler = (IConfigurationSectionHandler)Activator.CreateInstance(sectionHandlerType);
        }
        catch (InvalidCastException ex)
        {
            throw new InvalidOperationException(string.Format("Section handler type '{0}' does not implement IConfigurationSectionHandler.", sectionInformation.Type), ex);
        }

        var rawXml = sectionInformation.GetRawXml();
        if (rawXml == null)
        {
            return default(T);
        }

        var xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(rawXml);

        return (T)sectionHandler.Create(null, null, xmlDocument.DocumentElement);
    }
}

La manière dont vous l'appelleriez dans votre exemple est la suivante:

var map = new ExeConfigurationFileMap
{
    ExeConfigFilename = @"c:\\foo.config"
};
var configuration = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
var myParamsSection = configuration.GetSection("MyParams");
var myParamsCollection = myParamsSection.GetAs<NameValueCollection>();
8
Steven Padfield

C'est une vieille question, mais j'utilise la classe suivante pour faire le travail. Il est basé sur blog de Scott Dorman :

public class NameValueCollectionConfigurationSection : ConfigurationSection
{
    private const string COLLECTION_PROP_NAME = "";

    public IEnumerable<KeyValuePair<string, string>> GetNameValueItems()
    {
        foreach ( string key in this.ConfigurationCollection.AllKeys )
        {
            NameValueConfigurationElement confElement = this.ConfigurationCollection[key];
            yield return new KeyValuePair<string, string>
                (confElement.Name, confElement.Value);
        }
    }

    [ConfigurationProperty(COLLECTION_PROP_NAME, IsDefaultCollection = true)]
    protected NameValueConfigurationCollection ConfCollection
    {
        get
        {
            return (NameValueConfigurationCollection) base[COLLECTION_PROP_NAME];
        }
    }

L'utilisation est simple:

Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
NameValueCollectionConfigurationSection config = 
    (NameValueCollectionConfigurationSection) configuration.GetSection("MyParams");

NameValueCollection myParamsCollection = new NameValueCollection();
config.GetNameValueItems().ToList().ForEach(kvp => myParamsCollection.Add(kvp));
3
Peter Ivan

Voici quelques exemples de ce blog mentionné plus tôt:

<configuration>    
   <Database>    
      <add key="ConnectionString" value="data source=.;initial catalog=NorthWind;integrated security=SSPI"/>    
   </Database>    
</configuration>  

obtenir des valeurs:

 NameValueCollection db = (NameValueCollection)ConfigurationSettings.GetConfig("Database");         
    labelConnection2.Text = db["ConnectionString"];

-

Un autre exemple:

<Locations 
   ImportDirectory="C:\Import\Inbox"
   ProcessedDirectory ="C:\Import\Processed"
   RejectedDirectory ="C:\Import\Rejected"
/>

obtenir de la valeur:

Hashtable loc = (Hashtable)ConfigurationSettings.GetConfig("Locations"); 

labelImport2.Text = loc["ImportDirectory"].ToString();
labelProcessed2.Text = loc["ProcessedDirectory"].ToString();
2
RayLoveless