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

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
}

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
}

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

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

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

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


2

Creo que la expresión LINQ puede ser mejor:

   const string MyKey = "myKey"

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

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

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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.