Comment vérifier si une clé appSettings existe?

146

Comment vérifier si un paramètre d'application est disponible?

ie app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key ="someKey" value="someValue"/>
  </appSettings>
</configuration>

et dans le fichier de code

if (ConfigurationManager.AppSettings.ContainsKey("someKey"))
{
  // Do Something
}else{
  // Do Something Else
}
bitcycle
la source

Réponses:

223

MSDN: Configuration Manager.AppSettings

if (ConfigurationManager.AppSettings[name] != null)
{
// Now do your magic..
}

ou

string s = ConfigurationManager.AppSettings["myKey"];
if (!String.IsNullOrEmpty(s))
{
    // Key exists
}
else
{
    // Key doesn't exist
}

la source
2
Nous avons une fonction IsNull de type SQL dans notre bibliothèque qui rend la récupération d'un paramètre très pratique:Dim configValue As String = Util.IsNull(ConfigurationManager.AppSettings.Get("SettingName"), String.Empty)
Eirik H
10
Il lance "La référence d'objet n'est pas définie sur une instance d'un objet"
Waqar Alamgir
Non, c'est faux. Si "myKey" n'existe pas dans le nœud xml des paramètres de l'application, le code a renvoyé une exception.
Gionata
si vous vérifiez IsNullOrEmpty, votre logique pour "clé n'existe pas" s'exécutera lorsque vous aurez en fait une clé avec une valeur de chaîne vide comme paramètre valide
nrjohnstone
3
pas la meilleure réponse car cela jette des exceptions. Divyesh Patel est une meilleure solution.
VRPF
81
if (ConfigurationManager.AppSettings.AllKeys.Contains("myKey"))
{
    // Key exists
}
else
{
    // Key doesn't exist
}
Divyesh Patel
la source
Ce serait probablement un peu plus efficace (?) Si vous n'aviez aucune envie d'utiliser la valeur par la suite. La question mentionne spécifiquement le test «si un paramètre d'application est disponible». Étant donné que la disponibilité implique le désir de l'utiliser dans mon esprit, je dirais que la réponse fournie par user195488 sera plus utile aux personnes qui viennent ici - mais à proprement parler, votre réponse est également correcte.
Code Jockey du
10
C'est une bien meilleure solution pour le simple fait qu'il vérifie réellement si la clé existe. Si j'ai une valeur vide pour ma clé, la solution fournie par user195488 me donnerait un faux positif.
dyslexicanaboko
6
Cette solution est incorrecte. AppSettings est un NameValueCollection qui, par défaut, est insensible à la casse en ce qui concerne les recherches de clés. Cependant, la méthode d'extension LINQ .Contains que vous utilisez ici utilisera par défaut une comparaison sensible à la casse .
Jax
9

Valeur par défaut renvoyée en toute sécurité via les génériques et LINQ.

public T ReadAppSetting<T>(string searchKey, T defaultValue, StringComparison compare = StringComparison.Ordinal)
{
    if (ConfigurationManager.AppSettings.AllKeys.Any(key => string.Compare(key, searchKey, compare) == 0)) {
        try
        { // see if it can be converted.
            var converter = TypeDescriptor.GetConverter(typeof(T));
            if (converter != null) defaultValue = (T)converter.ConvertFromString(ConfigurationManager.AppSettings.GetValues(searchKey).First());
        }
        catch { } // nothing to do just return the defaultValue
    }
    return defaultValue;
}

Utilisé comme suit:

string LogFileName = ReadAppSetting("LogFile","LogFile");
double DefaultWidth = ReadAppSetting("Width",1280.0);
double DefaultHeight = ReadAppSetting("Height",1024.0);
Color DefaultColor = ReadAppSetting("Color",Colors.Black);
codebender
la source
ConfigurationManager.AppSettingsn'est pas sensible à la casse, Any(key => key == MyKeycependant
janv8000
@ janv8000 Je voulais la sensibilité à la casse, mais j'ai mis à jour l'exemple pour le gérer.
codebender
Les comparaisons appropriées insensibles à la casse sont plus rapides avec ToUpper (voir stackoverflow.com/a/12137/389424 ). Encore mieux est d'utiliser la surcharge string.Equals () en passant un StringComparisonType.
janv8000
C'est une très bonne solution au problème. J'ai un peu modifié l'implémentation pour prendre en charge le concept des paramètres requis. Juste une chose - n'oubliez pas d'ajouter une using System.ComponentModel;déclaration à votre classe pour soutenir l'utilisation de la TypeDescriptorclasse.
STLDev
3
var isAlaCarte = 
    ConfigurationManager.AppSettings.AllKeys.Contains("IsALaCarte") && 
    bool.Parse(ConfigurationManager.AppSettings.Get("IsALaCarte"));
Johnny Trinh
la source
2

Si la clé que vous recherchez n'est pas présente dans le fichier de configuration, vous ne pourrez pas la convertir en chaîne avec .ToString () car la valeur sera nulle et vous obtiendrez un "Référence d'objet non définie à une instance d'une erreur d'objet ". Il est préférable de voir d'abord si la valeur existe avant d'essayer d'obtenir la représentation sous forme de chaîne.

if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["myKey"]))
{
    String myKey = ConfigurationManager.AppSettings["myKey"].ToString();
}

Ou, comme Code Monkey l'a suggéré:

if (ConfigurationSettings.AppSettings["myKey"] != null)
{
// Now do your magic..
}
John Craft
la source
2

Les options supérieures offrent une flexibilité à tous les niveaux, si vous connaissez le type de clé, essayez de les analyser bool.TryParse(ConfigurationManager.AppSettings["myKey"], out myvariable);

sam
la source
2

Je pense que l'expression LINQ peut être la meilleure:

   const string MyKey = "myKey"

   if (ConfigurationManager.AppSettings.AllKeys.Any(key => key == MyKey))
          {
              // Key exists
          }
Mike Gold
la source
bien sûr ... mais idunno - y a-t-il un avantage à cette méthode? Si je connais VRAIMENT bien Linq (ce que la plupart des programmeurs C # finiront probablement par être), alors il serait probablement aussi facile de lire cet exemple, mais je ne pense pas que ce serait plus facile - donc à moins qu'il y ait un avantage d'efficacité ... Pourquoi?
Code Jockey du
aucun avantage d'efficacité et imo syntaxiquement verbeux.
John Nicholas
1
ConfigurationManager.AppSettingsn'est pas sensible à la casse, Any(key => key == MyKeycependant
janv8000
1

J'ai aimé la réponse de codebender , mais j'en avais besoin pour fonctionner en C ++ / CLI. C'est ce avec quoi j'ai fini. Il n'y a pas d'utilisation LINQ, mais fonctionne.

generic <typename T> T MyClass::ReadAppSetting(String^ searchKey, T defaultValue) {
  for each (String^ setting in ConfigurationManager::AppSettings->AllKeys) {
    if (setting->Equals(searchKey)) { //  if the key is in the app.config
      try {                           // see if it can be converted
        auto converter = TypeDescriptor::GetConverter((Type^)(T::typeid)); 
        if (converter != nullptr) { return (T)converter->ConvertFromString(ConfigurationManager::AppSettings[searchKey]); }
      } catch (Exception^ ex) {} // nothing to do
    }
  }
  return defaultValue;
}
Nimchimpsky
la source
0

L'utilisation de la nouvelle syntaxe c # avec TryParse a bien fonctionné pour moi:

  // TimeOut
  if (int.TryParse(ConfigurationManager.AppSettings["timeOut"], out int timeOut))
  {
     this.timeOut = timeOut;
  }
Reinier van de Wetering
la source
Bienvenue à SO! Lorsque vous postez une réponse, essayez d'expliquer un peu votre solution. Dans ce cas, il y a encore quelques réponses, essayez d'exposer les pros dans les vôtres.
David García Bodego