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
}

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
}

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
}

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);

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"));

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..
}

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);


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
          }

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;
}

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;
  }

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.