Como verificar se existe uma chave appSettings?


146

Como verifico se uma Configuração de aplicativo está disponível?

ou seja, app.config

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

e no codefile

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

Respostas:


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
Nós temos uma função SQL-like IsNull em nossa biblioteca que torna a recuperação de uma configuração muito útil:Dim configValue As String = Util.IsNull(ConfigurationManager.AppSettings.Get("SettingName"), String.Empty)
— Eirik H

10
Ele lança "Referência de objeto não definida para uma instância de um objeto"
— Waqar Alamgir 3/13/13

Não, está errado. Se "myKey" não existir no nó xml das configurações do aplicativo, o código gerará uma exceção.
— Gionata #

se você verificar para IsNullOrEmpty então sua lógica de "chave não existe" será executado quando você realmente tem uma chave com um valor de string em branco como uma configuração válida
— nrjohnstone

3
Não é a melhor resposta, pois isso gera exceções. Divyesh Patel é uma solução melhor.
— VRPF

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

Provavelmente seria um pouco mais eficiente (?) Se você não desejasse usar o valor posteriormente. A pergunta menciona especificamente o teste 'se uma configuração de aplicativo estiver disponível'. Como a Disponibilidade implica em um desejo de usá-lo em minha mente, eu diria que a resposta fornecida pelo usuário195488 será mais útil para as pessoas que vêm aqui - mas, estritamente falando, sua resposta também está correta.
— Code Jockey

10
Essa é uma solução muito melhor pelo simples fato de estar realmente verificando se a chave existe. Se eu tiver um valor em branco para minha chave, a solução fornecida pelo usuário195488 me fornecerá um falso positivo.
— Dislexicanaboko

6
Esta solução está incorreta. AppSettings é um NameValueCollection que, por padrão, não diferencia maiúsculas de minúsculas quando se trata de pesquisas principais. O método de extensão LINQ .Contains que você está usando aqui, no entanto, usará como padrão uma comparação que diferencia maiúsculas de minúsculas .
— Jax

9

Valor padrão retornado com segurança via genéricos 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;
}

Utilizado da seguinte forma:

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ão Any(key => key == MyKeyfaz
— distinção entre

@ janv8000 Eu queria distinção entre maiúsculas e minúsculas, mas atualizei o exemplo para lidar com isso.
— Codebender

As comparações que não diferenciam maiúsculas de minúsculas são mais rápidas com o ToUpper (consulte stackoverflow.com/a/12137/389424 ). O melhor apostador é usar a sobrecarga string.Equals () passando um StringComparisonType.
— janv8000

Esta é realmente uma ótima solução para o problema. Modifiquei um pouco a implementação para dar suporte ao conceito de configurações necessárias. Apenas uma coisa - lembre-se de adicionar uma using System.ComponentModel;declaração à sua classe para apoiar o uso da TypeDescriptorclasse.
— STLDev 24/08/19

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

2

Se a chave que você está procurando não estiver presente no arquivo de configuração, você não poderá convertê-la em uma string com .ToString () porque o valor será nulo e você receberá uma "Referência de objeto não definida para uma instância de um objeto ". É melhor ver primeiro se o valor existe antes de tentar obter a representação da string.

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

Ou, como o Code Monkey sugeriu:

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

2

As opções superiores oferecem flexibilidade para todos os tipos, se você souber o tipo de chave, tente analisá-las bool.TryParse(ConfigurationManager.AppSettings["myKey"], out myvariable);


2

Eu acho que a expressão LINQ pode ser melhor:

   const string MyKey = "myKey"

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

claro ... mas idunno - existe alguma vantagem nesse método? Se eu sou MUITO versado no Linq (o que a maioria dos programadores de C # provavelmente acabará por fazer), provavelmente seria tão fácil ler este exemplo, mas acho que nunca seria mais fácil - portanto, a menos que haja uma vantagem de eficiência ... porque?
— Code Jockey

nenhuma vantagem de eficiência e imo sintaticamente detalhado.
— John

1
ConfigurationManager.AppSettingsnão Any(key => key == MyKey
— diferencia

1

Gostei da resposta do codebender , mas precisava que ele funcionasse em C ++ / CLI. Foi assim que acabei. Não há uso do LINQ, mas 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 a nova sintaxe c # com o TryParse funcionou bem para mim:

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

Bem-vindo ao SO! Quando você postar uma resposta, tente explicar um pouco a sua solução. Nesse caso, existem mais algumas respostas, tente expor os profissionais nos seus.
— David García Bodego 31/10/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.