168

How do I check to see if an Application Setting is available?

i.e. app.config

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

and in the codefile

if (ConfigurationManager.AppSettings.ContainsKey("someKey"))
{
  // Do Something
}else{
  // Do Something Else
}
user247702
  • 23,641
  • 15
  • 110
  • 157
bitcycle
  • 7,632
  • 16
  • 70
  • 121

9 Answers9

246

MSDN: Configuration Manager.AppSettings

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

or

string s = ConfigurationManager.AppSettings["myKey"];
if (!String.IsNullOrEmpty(s))
{
    // Key exists
}
else
{
    // Key doesn't exist
}
  • 2
    We have a [SQL-like IsNull function](https://gist.github.com/eithe/5589891) in our library which makes retrieving a setting very handy: `Dim configValue As String = Util.IsNull(ConfigurationManager.AppSettings.Get("SettingName"), String.Empty)` – Eirik H May 16 '13 at 07:00
  • 14
    It throws "Object reference not set to an instance of an object" – Waqar Alamgir Jun 03 '13 at 08:14
  • 3
    No, it's wrong. If "myKey" does not exists in the app settings xml node, the code thrown an exception. – Gionata Jun 27 '16 at 10:41
  • 3
    if you check for IsNullOrEmpty then your logic for "key doesn't exist" will run when you actually have a key with a blank string value as a valid setting – nrjohnstone Jul 07 '16 at 09:28
  • 4
    not the best answer as this throws exceptions. Divyesh Patel is a better solution. – VRPF Oct 18 '16 at 06:46
  • This works for me and does not throw an exception. Maybe .net 4.5 works differently. You sure you didn't try and call a null function on the string? – Brain2000 Nov 03 '16 at 18:12
  • `NameValueCollection[string]` ( https://msdn.microsoft.com/en-us/library/8d0bzeeb.aspx ) doesn't throw when the setting is nonexistent, it returns null. – Medinoc Jun 27 '17 at 16:07
  • 2
    If doesn't throw exception using .net 4.5. If my setting is present but contains empty or null value it returns false positive. There should be a `HasKey()` or something like in that way method. The answer provided by Divyesh Patel is more correct. – broadband Jun 21 '18 at 11:29
  • You should retain only the first part, snippet after the or doesn't take into account present but empty values – janv8000 Dec 19 '18 at 14:12
  • The IsNullOrEmpty() method works for me against .NET 4.0 (does not throw error if the key doesn't exist in web.config). But the other commenters are correct that using this method we must take into account a present but empty string for this value in the config file. In my case, I wanted the same behavior whether the setting was missing or present but empty, so it worked out for me. – dwillis77 Jul 29 '19 at 01:56
  • It throws "Object reference not set to an instance of an object" for me running .Net 4.7.2 – Mauro Gagna Jul 06 '22 at 00:02
97
if (ConfigurationManager.AppSettings.Settings.AllKeys.Contains("myKey"))
{
    // Key exists
}
else
{
    // Key doesn't exist
}
Gorodeckij Dimitrij
  • 4,209
  • 2
  • 17
  • 21
Divyesh Patel
  • 1,147
  • 8
  • 4
  • This would probably be slightly more efficient (?) if you had no desire to use the value afterwards. The question specifically mentions testing 'if an Application Setting is available'. Since Availability implies a desire to use it in my mind, I'd say the answer provided by user195488 will be more useful to people coming here - but strictly speaking, your answer is also correct. – Code Jockey Sep 11 '14 at 19:09
  • 11
    This is a far better solution for the simple fact that it is actually checking if the key exists. If I have blank value for my key, the solution provided by user195488 would give me a false positive. – dyslexicanaboko Sep 30 '14 at 19:40
  • 9
    This solution is incorrect. AppSettings is a NameValueCollection which by default is **case-insensitive** when it comes to key lookups. The LINQ .Contains extension method you're using here however will default to a **case-sensitive** comparison. – Jax Jun 04 '15 at 19:00
  • I like this one, as if I send key name that not present, its work correctly and answer above give reference null error. – Gorodeckij Dimitrij Jul 04 '22 at 21:54
10

Safely returned default value via generics and 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;
}

Used as follows:

string LogFileName = ReadAppSetting("LogFile","LogFile");
double DefaultWidth = ReadAppSetting("Width",1280.0);
double DefaultHeight = ReadAppSetting("Height",1024.0);
Color DefaultColor = ReadAppSetting("Color",Colors.Black);
codebender
  • 469
  • 1
  • 6
  • 23
  • 1
    `ConfigurationManager.AppSettings` is not case-sensitive, `Any(key => key == MyKey` however is – janv8000 Dec 19 '18 at 14:12
  • @janv8000 I wanted case sensitivity, but updated the example to handle it. – codebender Dec 19 '18 at 21:47
  • Proper case-insensitive comparisons are faster with ToUpper (see https://stackoverflow.com/a/12137/389424). Even beter is to use the string.Equals() overload passing a StringComparisonType. – janv8000 Dec 20 '18 at 06:02
  • This is a really great solution to the issue. I've modified the implementation a bit to support the concept of required settings. Just one thing - remember to add `using System.ComponentModel;` statement to your class to support use of the `TypeDescriptor` class. – STLDev Aug 24 '19 at 21:08
3
var isAlaCarte = 
    ConfigurationManager.AppSettings.AllKeys.Contains("IsALaCarte") && 
    bool.Parse(ConfigurationManager.AppSettings.Get("IsALaCarte"));
Chris Catignani
  • 5,040
  • 16
  • 42
  • 49
2

I think the LINQ expression may be best:

   const string MyKey = "myKey"

   if (ConfigurationManager.AppSettings.AllKeys.Any(key => key == MyKey))
          {
              // Key exists
          }
mike gold
  • 1,551
  • 12
  • 12
  • sure... but idunno - is there any _advantage_ to this method? If I'm REALLY well versed in Linq (which most C# programmers probably eventually will be), then it would probably be _as easy_ to read this example, but I don't think it would ever be _easier_ - so unless there's an efficiency advantage... why? – Code Jockey Sep 11 '14 at 19:12
  • no efficiency advantage and syntactically verbose imo. – John Nicholas Oct 06 '15 at 14:51
  • 1
    `ConfigurationManager.AppSettings` is not case-sensitive, `Any(key => key == MyKey` however is – janv8000 Dec 19 '18 at 14:10
2

If the key you are looking for isn't present in the config file, you won't be able to convert it to a string with .ToString() because the value will be null and you'll get an "Object reference not set to an instance of an object" error. It's best to first see if the value exists before trying to get the string representation.

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

Or, as Code Monkey suggested:

if (ConfigurationSettings.AppSettings["myKey"] != null)
{
// Now do your magic..
}
John Craft
  • 131
  • 1
  • 7
2

Upper options gives flexible to all manner, if you know key type try parsing them bool.TryParse(ConfigurationManager.AppSettings["myKey"], out myvariable);

sam
  • 21
  • 1
1

I liked codebender's answer, but needed it to work in C++/CLI. This is what I ended up with. There's no LINQ usage, but works.

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
  • 99
  • 11
0

Using the new c# syntax with TryParse worked well for me:

  // TimeOut
  if (int.TryParse(ConfigurationManager.AppSettings["timeOut"], out int timeOut))
  {
     this.timeOut = timeOut;
  }
  • 1
    Welcome to SO! When you post answer, please try to explain your solution a little bit. In this case, there are a few more answers, try to expose the Pros in yours. – David García Bodego Oct 31 '19 at 03:22