Как проверить, существует ли ключ appSettings?


146

Как проверить, доступна ли настройка приложения?

то есть app.config

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

и в кодовом файле

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

Ответы:


223

MSDN: Configuration Manager.AppSettings

if (ConfigurationManager.AppSettings[name] != null)
{
// Now do your magic..
}

или

string s = ConfigurationManager.AppSettings["myKey"];
if (!String.IsNullOrEmpty(s))
{
    // Key exists
}
else
{
    // Key doesn't exist
}

2
В нашей библиотеке есть SQL-подобная функция IsNull, которая делает получение параметров очень удобным:Dim configValue As String = Util.IsNull(ConfigurationManager.AppSettings.Get("SettingName"), String.Empty)
— Eirik H

10
Он выдает «Ссылка на объект не установлена ​​для экземпляра объекта»
— Вакар Аламгир

Нет, это не так. Если «myKey» не существует в xml-узле настроек приложения, код выдает исключение.
— Гионата

если вы проверите IsNullOrEmpty, тогда ваша логика «ключ не существует» будет работать, когда у вас фактически есть ключ с пустым строковым значением в качестве допустимой установки
— nrjohnstone

3
не самый лучший ответ, поскольку это создает исключения. Дивьеш Патель - лучшее решение.
— VRPF

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

Вероятно, это было бы немного более эффективно (?), Если бы у вас не было желания использовать значение впоследствии. В частности, в вопросе упоминается проверка «доступна ли настройка приложения». Поскольку доступность подразумевает желание использовать ее в моем сознании, я бы сказал, что ответ пользователя 195488 будет более полезным для людей, которые приходят сюда, но, строго говоря, ваш ответ также верен.
— Код жокея

10
Это гораздо лучшее решение для простого факта, что он фактически проверяет, существует ли ключ. Если у меня есть пустое значение для моего ключа, решение, предоставленное user195488, даст мне ложное срабатывание.
— дислексиканабоко

6
Это решение неверно. AppSettings - это NameValueCollection, которая по умолчанию нечувствительна к регистру, когда дело доходит до поиска ключей. Используемый здесь метод расширения LINQ .Contains, однако, по умолчанию сравнивается с учетом регистра .
— Jax

9

Безопасно вернул значение по умолчанию через дженерики и 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;
}

Используется следующим образом:

string LogFileName = ReadAppSetting("LogFile","LogFile");
double DefaultWidth = ReadAppSetting("Width",1280.0);
double DefaultHeight = ReadAppSetting("Height",1024.0);
Color DefaultColor = ReadAppSetting("Color",Colors.Black);

ConfigurationManager.AppSettingsне чувствителен к регистру, Any(key => key == MyKeyоднако
— janv8000

@ janv8000 Я хотел, чтобы чувствительность к регистру, но обновил пример, чтобы справиться с этим.
— Codebender

Надлежащие сравнения без учета регистра быстрее с ToUpper (см. Stackoverflow.com/a/12137/389424 ). Еще лучше использовать перегрузку string.Equals (), передающую StringComparisonType.
— января

Это действительно отличное решение проблемы. Я немного изменил реализацию, чтобы поддержать концепцию необходимых настроек. Только одно - не забудьте добавить using System.ComponentModel;оператор в ваш класс для поддержки использования TypeDescriptorкласса.
— STLDev


2

Если искомый ключ отсутствует в файле конфигурации, вы не сможете преобразовать его в строку с помощью .ToString (), поскольку значение будет нулевым, и вы получите «Ссылка на объект не установлена» к экземпляру объекта "ошибка. Лучше сначала проверить, существует ли значение, прежде чем пытаться получить строковое представление.

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

Или, как предложил Code Monkey:

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

2

Верхние параметры дают гибкость во всех отношениях, если вы знаете тип ключа, попробуйте их проанализировать bool.TryParse(ConfigurationManager.AppSettings["myKey"], out myvariable);


2

Я думаю, что выражение LINQ может быть лучшим:

   const string MyKey = "myKey"

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

конечно ... но idunno - есть ли преимущество этого метода? Если я ДЕЙСТВИТЕЛЬНО хорошо разбираюсь в Linq (что, вероятно, в конечном итоге и придет большинство программистов на C #), то этот пример, вероятно, будет так же легко прочитать, но я не думаю, что когда-либо будет легче - так что если нет преимущества в эффективности ... Зачем?
— Код жокея

нет преимущества в эффективности и синтаксически многословно.
— Джон Николас

1
ConfigurationManager.AppSettingsне чувствителен к регистру, Any(key => key == MyKeyоднако
— janv8000

1

Мне понравился ответ codebender , но он нужен для работы в C ++ / CLI. Это то, что я закончил. Там нет использования LINQ, но работает.

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

Использование нового синтаксиса c # с TryParse хорошо для меня:

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

Добро пожаловать на ТАК! Когда вы отправляете ответ, пожалуйста, попробуйте немного объяснить свое решение. В этом случае есть еще несколько ответов, попробуйте выставить плюсы в свой.
— Дэвид Гарсия Бодего
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.