¿Cómo verificar si existe una clave de configuración de la aplicación?

146

¿Cómo verifico si hay una Configuración de aplicación disponible?

es decir, app.config

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

y en el archivo de código

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

Respuestas:

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
}

fuente
2
Tenemos una función IsNull similar a SQL en nuestra biblioteca que hace que recuperar una configuración sea muy útil:Dim configValue As String = Util.IsNull(ConfigurationManager.AppSettings.Get("SettingName"), String.Empty)
Eirik H
10
Lanza "Referencia de objeto no establecida a una instancia de un objeto"
Waqar Alamgir
No, esta mal. Si "myKey" no existe en el nodo xml de configuración de la aplicación, el código arrojó una excepción.
Gionata
si verifica IsNullOrEmpty, su lógica para "la clave no existe" se ejecutará cuando realmente tenga una clave con un valor de cadena en blanco como una configuración válida
nrjohnstone
3
No es la mejor respuesta ya que esto arroja excepciones. Divyesh Patel es una mejor solución.
VRPF
81
if (ConfigurationManager.AppSettings.AllKeys.Contains("myKey"))
{
    // Key exists
}
else
{
    // Key doesn't exist
}
Divyesh Patel
fuente
Esto probablemente sería un poco más eficiente (?) Si no deseara usar el valor después. La pregunta menciona específicamente la prueba "si hay una configuración de aplicación disponible". Dado que la disponibilidad implica un deseo de usarlo en mi mente, diría que la respuesta proporcionada por el usuario 194848 será más útil para las personas que vienen aquí, pero estrictamente hablando, su respuesta también es correcta.
Code Jockey
10
Esta es una solución mucho mejor por el simple hecho de que en realidad está verificando si la clave existe. Si tengo un valor en blanco para mi clave, la solución proporcionada por user195488 me daría un falso positivo.
dyslexicanaboko
66
Esta solución es incorrecta. AppSettings es una NameValueCollection que, por defecto, no distingue entre mayúsculas y minúsculas cuando se trata de búsquedas de claves. Sin embargo, el método de extensión LINQ .Contains que está utilizando aquí, por defecto, será una comparación entre mayúsculas y minúsculas .
Jax
9

Valor predeterminado devuelto de forma segura a través de genéricos y 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;
}

Usado de la siguiente manera:

string LogFileName = ReadAppSetting("LogFile","LogFile");
double DefaultWidth = ReadAppSetting("Width",1280.0);
double DefaultHeight = ReadAppSetting("Height",1024.0);
Color DefaultColor = ReadAppSetting("Color",Colors.Black);
codebender
fuente
ConfigurationManager.AppSettingssin Any(key => key == MyKeyembargo , no
distingue entre
@ janv8000 Quería mayúsculas y minúsculas, pero actualicé el ejemplo para manejarlo.
codebender
Las comparaciones que no distinguen entre mayúsculas y minúsculas son más rápidas con ToUpper (consulte stackoverflow.com/a/12137/389424 ). Incluso mejor es usar la sobrecarga string.Equals () pasando un StringComparisonType.
janv8000
Esta es una gran solución al problema. Modifiqué un poco la implementación para admitir el concepto de configuración requerida. Solo una cosa: recuerde agregar una using System.ComponentModel;declaración a su clase para apoyar el uso de la TypeDescriptorclase.
STLDev
3
var isAlaCarte = 
    ConfigurationManager.AppSettings.AllKeys.Contains("IsALaCarte") && 
    bool.Parse(ConfigurationManager.AppSettings.Get("IsALaCarte"));
Johnny Trinh
fuente
2

Si la clave que busca no está presente en el archivo de configuración, no podrá convertirla en una cadena con .ToString () porque el valor será nulo y obtendrá una "Referencia de objeto no establecida a una instancia de un objeto "error. Es mejor ver primero si el valor existe antes de intentar obtener la representación de cadena.

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

O, como sugirió Code Monkey:

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

Las opciones superiores ofrecen flexibilidad en todos los aspectos, si conoce el tipo de clave, intente analizarlas bool.TryParse(ConfigurationManager.AppSettings["myKey"], out myvariable);

sam
fuente
2

Creo que la expresión LINQ puede ser mejor:

   const string MyKey = "myKey"

   if (ConfigurationManager.AppSettings.AllKeys.Any(key => key == MyKey))
          {
              // Key exists
          }
mike gold
fuente
claro ... pero idunno, ¿hay alguna ventaja en este método? Si REALMENTE estoy bien versado en Linq (que la mayoría de los programadores de C # probablemente lo serán eventualmente), entonces probablemente sería tan fácil leer este ejemplo, pero no creo que alguna vez sea más fácil , así que a menos que haya una ventaja de eficiencia ... ¿por qué?
Code Jockey
sin ventaja de eficiencia y sintácticamente detallado imo.
John Nicholas
1
ConfigurationManager.AppSettingses no entre mayúsculas y minúsculas, Any(key => key == MyKeysin embargo, es
janv8000
1

Me gustó la respuesta de codebender , pero necesitaba que funcionara en C ++ / CLI. Esto es con lo que terminé. No hay uso de LINQ, pero funciona.

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

Usar la nueva sintaxis de C # con TryParse funcionó bien para mí:

  // TimeOut
  if (int.TryParse(ConfigurationManager.AppSettings["timeOut"], out int timeOut))
  {
     this.timeOut = timeOut;
  }
Reinier van de Wetering
fuente
Bienvenido a SO! Cuando publique una respuesta, intente explicar un poco su solución. En este caso, hay algunas respuestas más, intente exponer a los profesionales en la suya.
David García Bodego