Web.config and App.config variables can be fully type safe

I’m going to introduce a MUCH better way of accessing your variables that you have created in your web.config or app.config file.  Most likely, you’re probably storing your variables in your .config file like this:

Click here to follow me on Google+.

 <appSettings> <add key="EMailAddress" value="me@something.com"/> <add key="IsProduction" value="true"/> <add key="MaxWait" value="15"/> appSettings>

And your code to access them probably looks like this:

this.EMailAddressLabel.Text = ConfigurationManager.AppSettings["EMailAddress"];if (ConfigurationManager.AppSettings["IsProduction"] == "true") this.NotProdNotifyLabel.visible = false;else this.NotProdNotifyLabel.visible = true;this.MaxWaitLabel.Text = "Maximum wait time is " + ConfigurationManager.AppSettings["MaxWait"] + " seconds";

That’s an awful lot of typing, has the potential for typos that aren’t caught by the editor or the compiler, doesn’t have intellisense, and is not type safe.


Visual Studio has a very easy to use and very powerful feature for creating and accessing config variables.

Now, depending on what version of Visual Studio you’re using, things could be different.  As of this writing, the latest version is Visual Studio 2010.  But, this feature is available going all the way back to the original version of Visual Studio .Net back in February 2003.  So, it’s supported in all versions, but there are differences, not in how you do it, but in what choices you’ve already made for existing apps.  First, I’ll discuss doing this the right way when creating a new app:

BTW, this works for ALL .Net apps, not just ASP.Net web apps.  It works for WinForms, ASP.Net MVC, ASP.Net, Console apps, Windows Service Apps…

I’ll be using an ASP.Net WebForms app as an example, because that’s where the differences lie between the different version of Visual Studio.Net.

First, we’ll work with making a New app.

    1. Create a web app app.  Depending on your version of Visual Studio, you might have an option for “Web Site”.  DON’T CHOOSE THAT!  This whole solution is unavailable for web sites.  It MUST be a web app!


  • Right-click your project and choose “Properties:


  1. image


  • Click on the “Settings” tab.


  1. image


  • Click on the link, “This project does not contain a default settings file.  Click here to create one.”


  1. image

Now, your app contains what’s needed to support your simple typed config variables.  Notice the new stuff added to your project?


Now, never look at it again.  I just wanted you to see that it’s there.  This adds no complication to your life because you’ll never use it directly.  It’s just generated code.  Put it out of your mind and never think of it again.

Notice the grid that showed up on the screen?


This is where you’ll create your config variables… not in the config file itself.  This simple tool will automatically add them to the config file for you.  You don’t have to putz around with the messy config file anymore for your config variables.  Now, let’s add the 3 config variables we used the old way from the top of this article:

For each variable we create, we can choose the type of that variable!  Check out what happens when I create the IsProduction variable:


I picked “bool” from the “Type” drop down list.  Look at the “Value” column.  Notice that it knows what is valid for a boolean?  I’ll pick “True”.

Now, when I add MaxWait, I’ve got some options.  I can make it an int to represent number of seconds, but in reality, it’s representing a time span.  Guess what?  .Net has a TimeSpan type!



It inserts a value for me, showing me the format I need.  That’s HH:MM:SS, BTW.  I can add a decimal after the seconds to get milliseconds, if I want.  There’s a way to do days too, but I’ll let you figure that out.

I’m going to enter 15 seconds:


Now, this is important (but simple).  I need to hit “save”.


Now, look at what it did to the config file:



Now, there’s one more thing I want to draw your attention to… and it’s not important that you know this because you’ll never need to mess with this, but I want to give you a glimpse under the hood of what else has happened:


Pop open the Settings.settings branch and open the Settings.Designer.cs file:


 1: //------------------------------------------------------------------------------
 2: // 
 3: // This code was generated by a tool.
 4: // Runtime Version:4.0.30319.237
 5: //
 6: // Changes to this file may cause incorrect behavior and will be lost if
 7: // the code is regenerated.
 8: // 
 9: //------------------------------------------------------------------------------
 11: namespace ConfigVarsSample.Properties {
 14:     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
 15:     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "")]
 16:  internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
 18:  private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
 20:  public static Settings Default {
 21:             get {
 22:  return defaultInstance;
 23:             }
 24:         }
 26:         [global::System.Configuration.ApplicationScopedSettingAttribute()]
 27:         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
 28:         [global::System.Configuration.DefaultSettingValueAttribute("me@something.com")]
 29:  public string EMailAddress {
 30:             get {
 31:  return ((string)(this["EMailAddress"]));
 32:             }
 33:         }
 35:         [global::System.Configuration.ApplicationScopedSettingAttribute()]
 36:         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
 37:         [global::System.Configuration.DefaultSettingValueAttribute("True")]
 38:  public bool IsProduction {
 39:             get {
 40:  return ((bool)(this["IsProduction"]));
 41:             }
 42:         }
 44:         [global::System.Configuration.ApplicationScopedSettingAttribute()]
 45:         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
 46:         [global::System.Configuration.DefaultSettingValueAttribute("00:00:15")]
 47:  public global::System.TimeSpan MaxWait {
 48:             get {
 49:  return ((global::System.TimeSpan)(this["MaxWait"]));
 50:             }
 51:         }
 52:     }
 53: }

This is the code that got generated for you.  Now, put it out of your mind (again), because you’ll never actually edit this file.

Now, remember the old way of accessing the config variables?

this.EMailAddressLabel.Text = ConfigurationManager.AppSettings["EMailAddress"];if (ConfigurationManager.AppSettings["IsProduction"] == "true") this.NotProdNotifyLabel.visible = false;else this.NotProdNotifyLabel.visible = true;this.MaxWaitLabel.Text = "Maximum wait time is " + ConfigurationManager.AppSettings["MaxWait"] + " seconds";

Here’s the new way:

Add this to your using section:




And in your code, you do this:


Notice how you get intellisense?!?!?  Let’s continue:

var settings = new Settings();this.EMailAddressLabel.Text = settings.EMailAddress;this.NotProdNotifyLabel.visible = !settings.IsProduction;this.MaxWaitLabel.Text = "Maximum wait time is " + settings.MaxWait.ToString();

See how much cleaner this code is?  And, since it’s typed, you can use the IsProduction variable as a boolean rather than examining the text value of it.  The MaxWait variable can actually be used in time and date functions and directly in calculations!

What have you gained?

    1. Intellisense.


  • Edit time typo checking.



  • Compile time error checking.



  • Strongly typed variables.



  • Code that won’t fail at run time.



  • .config files that you don’t have to edit directly as often.



  • Increased productivity.


See this image?


You’ll find an actual working version of it at the bottom of this article. Please click the appropriate buttons in it to let your friends know about this article.

Check back later for updates too!

Click here to follow me on Google+.

Leave a Reply