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
}
bitcycle
fonte

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
}

fonte
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
}
Divyesh Patel
fonte
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);
codebender
fonte
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"));
Johnny Trinh
fonte
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..
}
John Craft
fonte
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);

sam
fonte
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
          }
microfone de ouro
fonte
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;
}
nimchimpsky
fonte
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;
  }
Reinier van de Wetering
fonte
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