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.