Wie überprüfe ich, ob ein appSettings-Schlüssel vorhanden ist?

146

Wie überprüfe ich, ob eine Anwendungseinstellung verfügbar ist?

dh app.config

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

und in der Codedatei

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

Antworten:

223

MSDN: Configuration Manager.AppSettings

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

oder

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

quelle
2
Wir haben eine SQL-ähnliche IsNull-Funktion in unserer Bibliothek, die das Abrufen einer Einstellung sehr praktisch macht:Dim configValue As String = Util.IsNull(ConfigurationManager.AppSettings.Get("SettingName"), String.Empty)
Eirik H
10
Es wirft "Objektreferenz nicht auf eine Instanz eines Objekts gesetzt"
Waqar Alamgir
Nein das ist falsch. Wenn "myKey" im XML-Knoten der App-Einstellungen nicht vorhanden ist, hat der Code eine Ausnahme ausgelöst.
Gionata
Wenn Sie nach IsNullOrEmpty suchen, wird Ihre Logik für "Schlüssel existiert nicht" ausgeführt, wenn Sie tatsächlich einen Schlüssel mit einem leeren Zeichenfolgenwert als gültige Einstellung haben
nrjohnstone
3
Nicht die beste Antwort, da dies Ausnahmen auslöst. Divyesh Patel ist eine bessere Lösung.
VRPF
81
if (ConfigurationManager.AppSettings.AllKeys.Contains("myKey"))
{
    // Key exists
}
else
{
    // Key doesn't exist
}
Divyesh Patel
quelle
Dies wäre wahrscheinlich etwas effizienter (?), Wenn Sie den Wert danach nicht mehr verwenden möchten. In der Frage wird speziell das Testen erwähnt, ob eine Anwendungseinstellung verfügbar ist. Da Verfügbarkeit den Wunsch impliziert, sie in meinem Kopf zu verwenden, würde ich sagen, dass die Antwort von user195488 für die Leute, die hierher kommen, nützlicher ist - aber genau genommen ist Ihre Antwort auch richtig.
Code Jockey
10
Dies ist eine weitaus bessere Lösung für die einfache Tatsache, dass tatsächlich geprüft wird, ob der Schlüssel vorhanden ist. Wenn ich einen leeren Wert für meinen Schlüssel habe, würde die von user195488 bereitgestellte Lösung mir ein falsches Positiv geben.
Legasthenikeraboko
6
Diese Lösung ist falsch. AppSettings ist eine NameValueCollection, bei der bei der Suche nach Schlüsseln standardmäßig die Groß- und Kleinschreibung nicht berücksichtigt wird . Die hier verwendete LINQ .Contains-Erweiterungsmethode verwendet jedoch standardmäßig einen Vergleich zwischen Groß- und Kleinschreibung .
Jax
9

Sicher zurückgegebener Standardwert über Generika und 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;
}

Wird wie folgt verwendet:

string LogFileName = ReadAppSetting("LogFile","LogFile");
double DefaultWidth = ReadAppSetting("Width",1280.0);
double DefaultHeight = ReadAppSetting("Height",1024.0);
Color DefaultColor = ReadAppSetting("Color",Colors.Black);
Codebender
quelle
ConfigurationManager.AppSettingsunterscheidet nicht zwischen Groß- und Kleinschreibung, ist Any(key => key == MyKeyjedoch
janv8000
@ janv8000 Ich wollte Groß- und Kleinschreibung beachten, habe aber das Beispiel aktualisiert, um damit umzugehen.
Codebender
Richtige Vergleiche ohne Berücksichtigung der Groß- und Kleinschreibung sind mit ToUpper schneller (siehe stackoverflow.com/a/12137/389424 ). Noch besser ist es, die Überladung string.Equals () zu verwenden, die einen StringComparisonType übergibt.
Januar 8000
Dies ist eine wirklich gute Lösung für das Problem. Ich habe die Implementierung ein wenig geändert, um das Konzept der erforderlichen Einstellungen zu unterstützen. Nur eine Sache - denken Sie daran using System.ComponentModel;, Ihrer Klasse eine Anweisung hinzuzufügen , um die Verwendung der Klasse zu unterstützen TypeDescriptor.
STLDev
3
var isAlaCarte = 
    ConfigurationManager.AppSettings.AllKeys.Contains("IsALaCarte") && 
    bool.Parse(ConfigurationManager.AppSettings.Get("IsALaCarte"));
Johnny Trinh
quelle
2

Wenn der gesuchte Schlüssel nicht in der Konfigurationsdatei vorhanden ist, können Sie ihn nicht mit .ToString () in eine Zeichenfolge konvertieren, da der Wert null ist und Sie eine "Objektreferenz nicht festgelegt" erhalten zu einer Instanz eines Objekts "Fehler. Überprüfen Sie am besten zuerst, ob der Wert vorhanden ist, bevor Sie versuchen, die Zeichenfolgendarstellung abzurufen.

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

Oder wie Code Monkey vorgeschlagen hat:

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

Die oberen Optionen sind in jeder Hinsicht flexibel. Wenn Sie den Schlüsseltyp kennen, versuchen Sie, sie zu analysieren bool.TryParse(ConfigurationManager.AppSettings["myKey"], out myvariable);

Sam
quelle
2

Ich denke, der LINQ-Ausdruck ist vielleicht der beste:

   const string MyKey = "myKey"

   if (ConfigurationManager.AppSettings.AllKeys.Any(key => key == MyKey))
          {
              // Key exists
          }
Mike Gold
quelle
sicher ... aber idunno - hat diese Methode einen Vorteil ? Wenn ich mich mit Linq wirklich gut auskenne (was die meisten C # -Programmierer wahrscheinlich irgendwann sein werden), wäre es wahrscheinlich genauso einfach , dieses Beispiel zu lesen, aber ich denke nicht, dass es jemals einfacher sein würde - es sei denn, es gibt einen Effizienzvorteil ... Warum?
Code Jockey
Kein Effizienzvorteil und syntaktisch ausführlich imo.
John Nicholas
1
ConfigurationManager.AppSettingsunterscheidet nicht zwischen Groß- und Kleinschreibung, ist Any(key => key == MyKeyjedoch
janv8000
1

Ich mochte die Antwort von Codebender , brauchte sie aber, um in C ++ / CLI zu funktionieren. Damit bin ich gelandet. Es gibt keine LINQ-Verwendung, aber es funktioniert.

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
quelle
0

Die Verwendung der neuen c # -Syntax mit TryParse hat bei mir gut funktioniert:

  // TimeOut
  if (int.TryParse(ConfigurationManager.AppSettings["timeOut"], out int timeOut))
  {
     this.timeOut = timeOut;
  }
Reinier van de Wetering
quelle
Willkommen bei SO! Wenn Sie eine Antwort posten, versuchen Sie bitte, Ihre Lösung ein wenig zu erklären. In diesem Fall gibt es noch ein paar Antworten. Versuchen Sie, die Vorteile in Ihren zu entlarven.
David García Bodego