Come verificare se esiste una chiave appSettings?


146

Come posso verificare se è disponibile un'impostazione dell'applicazione?

cioè app.config

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

e nel file di codice

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

Risposte:


223

MSDN: Configuration Manager.AppSettings

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

o

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

2
Abbiamo una funzione IsNull simile a SQL nella nostra libreria che rende molto utile il recupero di un'impostazione:Dim configValue As String = Util.IsNull(ConfigurationManager.AppSettings.Get("SettingName"), String.Empty)
Eirik H

10
Genera "Riferimento oggetto non impostato su un'istanza di un oggetto"
Waqar Alamgir,

No, è sbagliato. Se "myKey" non esiste nel nodo xml delle impostazioni dell'app, il codice ha generato un'eccezione.
Gionata,

se controlli IsNullOrEmpty, la tua logica per "chiave non esiste" verrà eseguita quando in realtà hai una chiave con un valore di stringa vuota come impostazione valida
nrjohnstone

3
non è la risposta migliore in quanto genera eccezioni. Divyesh Patel è una soluzione migliore.
VRPF,

81
if (ConfigurationManager.AppSettings.AllKeys.Contains("myKey"))
{
    // Key exists
}
else
{
    // Key doesn't exist
}

Questo sarebbe probabilmente leggermente più efficiente (?) Se non desiderassi utilizzare il valore in seguito. La domanda menziona specificamente il test "se è disponibile un'impostazione dell'applicazione". Poiché Disponibilità implica il desiderio di usarlo nella mia mente, direi che la risposta fornita dall'utente195488 sarà più utile per le persone che vengono qui - ma a rigor di termini, anche la tua risposta è corretta.
Codice Jockey

10
Questa è una soluzione molto migliore per il semplice fatto che sta effettivamente controllando se la chiave esiste. Se ho un valore vuoto per la mia chiave, la soluzione fornita da user195488 mi darebbe un falso positivo.
dyslexicanaboko,

6
Questa soluzione non è corretta AppSettings è un NameValueCollection che per impostazione predefinita non fa distinzione tra maiuscole e minuscole quando si tratta di ricerche chiave. Il metodo di estensione LINQ .Conten che stai utilizzando qui verrà impostato per impostazione predefinita su un confronto sensibile al maiuscolo / minuscolo .
Jax,

9

Valore predefinito restituito in modo sicuro tramite generics e 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;
}

Usato come segue:

string LogFileName = ReadAppSetting("LogFile","LogFile");
double DefaultWidth = ReadAppSetting("Width",1280.0);
double DefaultHeight = ReadAppSetting("Height",1024.0);
Color DefaultColor = ReadAppSetting("Color",Colors.Black);

ConfigurationManager.AppSettingsnon fa distinzione tra maiuscole e minuscole, Any(key => key == MyKeytuttavia lo è
janv8000,

@ janv8000 Volevo la distinzione tra maiuscole e minuscole, ma ho aggiornato l'esempio per gestirlo.
codebender

Confronti Proper case-insensitive sono più veloci con ToUpper (vedi stackoverflow.com/a/12137/389424 ). Ancora meglio è usare il sovraccarico string.Equals () passando un StringComparisonType.
Janv8000,

Questa è davvero un'ottima soluzione al problema. Ho modificato un po 'l'implementazione per supportare il concetto di impostazioni richieste. Solo una cosa: ricordati di aggiungere using System.ComponentModel;un'istruzione alla tua classe per supportare l'uso della TypeDescriptorclasse.
STLDev

3
var isAlaCarte = 
    ConfigurationManager.AppSettings.AllKeys.Contains("IsALaCarte") && 
    bool.Parse(ConfigurationManager.AppSettings.Get("IsALaCarte"));

2

Se la chiave che stai cercando non è presente nel file di configurazione, non sarai in grado di convertirla in una stringa con .ToString () perché il valore sarà nullo e otterrai un "Riferimento oggetto non impostato a un'istanza di un oggetto "errore. È meglio prima vedere se il valore esiste prima di provare a ottenere la rappresentazione di stringa.

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

Oppure, come suggerito da Code Monkey:

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

2

Le opzioni superiori offrono flessibilità in tutti i modi, se conosci il tipo di chiave prova ad analizzarle bool.TryParse(ConfigurationManager.AppSettings["myKey"], out myvariable);


2

Penso che l'espressione LINQ possa essere la migliore:

   const string MyKey = "myKey"

   if (ConfigurationManager.AppSettings.AllKeys.Any(key => key == MyKey))
          {
              // Key exists
          }

certo ... ma idunno - c'è qualche vantaggio in questo metodo? Se sono VERAMENTE esperto in Linq (che probabilmente alla fine sarà la maggior parte dei programmatori C #), allora sarebbe probabilmente facile leggere questo esempio, ma non penso che sarebbe mai più facile - quindi a meno che non ci sia un vantaggio in termini di efficienza ... perché?
Codice Jockey

nessun vantaggio in termini di efficienza e imo sintatticamente dettagliato.
John Nicholas,

1
ConfigurationManager.AppSettingsnon fa distinzione tra maiuscole e minuscole, Any(key => key == MyKeytuttavia lo è
janv8000

1

Mi è piaciuta la risposta di codebender , ma ne avevo bisogno per funzionare in C ++ / CLI. Questo è quello che ho finito. Non c'è utilizzo di LINQ, ma funziona.

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'uso della nuova sintassi c # con TryParse ha funzionato bene per me:

  // TimeOut
  if (int.TryParse(ConfigurationManager.AppSettings["timeOut"], out int timeOut))
  {
     this.timeOut = timeOut;
  }

Benvenuti in SO! Quando pubblichi una risposta, prova a spiegare un po 'la tua soluzione. In questo caso, ci sono alcune altre risposte, prova ad esporre i Pro nei tuoi.
David García Bodego,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.