Skip to content
Nubgrammer
Menu
  • Home
  • Contact Me
Menu

Managing App Configs with the ConfigurationManager

Posted on November 7, 2017September 24, 2018 by Tyler Sells

TL;DR:

So, ASP.NET has a build-in method for handling custom, user-specific app configs.  It’s called the ConfigurationManager, and I’ll show you how to use it.

Code is here, and the video is here (or down below, whatever floats your boat).

The ConfigurationManager

Before I show you the video, here’s what I’m doing and why.  While cleaning up my RSS Aggregator project, I realized there were a lot of things I could have and should have done better.  One of them being the manner in which I handled user-defined configuration data.  So I set out on a quest, and these are my findings.

What it does:

In a nutshell, the ConfigurationManager creates an XML file in the bin folder.  Throughout your application, you can read and write to it to save anything you might need to.  You can use this to save a key-value pair and get it when you need it.  In part 2.2 of my RSS Aggregator series, I use this to save user feeds and return them when I get ready to load and display the data from the RSS feeds.  I pulled it out because it’s fairly complex and merited it’s own video.

Also, a small disclaimer:  This tutorial is very loosely based on a Microsoft tutorial but I made several modifications;  all I really needed was the code for accessing the config file.

The Config file:

This is the what and where of the file that the ConfigurationManager creates:

ConfigurationManager Config file location

As you can see, there’s the exe.Config file.  To the right is all of the XML data that’s contained in it.  The ConfigurationManager does all of that XML stuff for us.  It’s pretty nifty, eh?  To abstract everything that’s going on here, I created a single Manager class that has several methods that handles everything.

The Add function:

public void Add(Item item)
{
    if (IsUnique(item.Key))
    {
        var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        var settings = config.AppSettings.Settings;
        settings.Add(item.Key, item.Data);
        config.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);
    }
    else
    {
        throw new ConfigurationErrorsException("Item Key: " + item.Key + " is not unique");
    }
}

Obviously, we’re passing in an Item here.  In this case, Item is just a class that has a Key and a Data property. (Just for testing, ya know)

IsUnique is just a helper method that makes sure a key that matches the one we’re trying to create doesn’t already exist in the config file.  If we had two items with the same key, the ConfigurationManager wouldn’t know which one to pick when we wanted to pull the matching data out. So, we’ll just throw a new ConfigurationErrorsException to tell whoever is above that we couldn’t add the item because it wasn’t unique.

This is the code that tells the ConfigurationManager what to do:

//Tells the ConfigurationManager to open the config file
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

//This is just a shortcut to get to the Settings property of the config file we opened
var settings = config.AppSettings.Settings;

//Let's add a key and some data to the settings
settings.Add(item.Key, item.Data);

//Save the config file
config.Save(ConfigurationSaveMode.Modified);

//This tells the ConfigurationManager that the next time it accesses that Settings section, we made some changes to it and it needs to be re-read from disk
ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);

The Remove function:

public void Remove(string key)
{
    var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    var settings = config.AppSettings.Settings;
    if (settings[key] != null)
    {
        settings.Remove(key);
    }
    else
    {
        throw new ConfigurationErrorsException(key + " does not exist or can't be read");
    }
    config.Save(ConfigurationSaveMode.Modified);
    ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);
}

The remove function is fairly self explanatory.  We’ve got the same garb as the Add function in terms of the ConfigurationManager stuff.  All we’re doing here is making sure the key actually exists before we try to remove it.

The Update Function:

public void Update(Item oldItem, Item newItem)
{
    var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    var settings = config.AppSettings.Settings;
    if (settings[oldItem.Key] == null)
    {
        throw new ConfigurationErrorsException("Cannot Update item " + oldItem.Key + " because it doesn't exist or can't be read");
    }
    else if (oldItem.Key != newItem.Key)
    {
        /********************   Small Bug   ********************
         * Removing the item before we check to make sure it is
         * unique in the add function can result in a situation
         * in which the old item gets removed while the new item
         * never gets added
         *******************************************************/
        /*Remove(oldItem.Key);  //original
        Add(newItem);*/
        Add(newItem); //Fix
        Remove(oldItem.Key); //Fix
    }
    else
    {
        settings[oldItem.Key].Value = newItem.Data;
        config.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);
    }
}

This one is a little more complex.  Same ole’ ConfigurationManager stuff, but this on does a few extra things.  First, we want to make sure we’re editing something that actually exists.  Then, if the new key value is different than the old value, we don’t want to update anything.  We just want to remove the old setting and add the new one.  This won’t affect the user in this case and it let’s us reuse code we’ve already written.  Now, about that gigantic comment…

When making the RSS Aggregator Part 2.2 video, I found a bug in this code.  What was happening is that because I removed the old item before checking to make sure the new item was unique, a situation can occur in which the new item never gets added into the config but the old one is gone as well.  Oops.  By simply changing the order in which we perform these actions, this bug is fixed.

Lastly, if we are just editing the data, we want to set the value of the old key to the new data.

The Final bit:

public List List()
{
    var items = new List();
    var AppSettings = ConfigurationManager.AppSettings;
    foreach (var key in AppSettings.AllKeys)
    {
        var item = new Item(key, AppSettings[key]);
        items.Add(item);
    }
    return items;
}

Last, but not least, w have the List() function.  All we’re doing is creating and returning a list of items based off the values stored in the config file.  This allows us to access these items in a useful manner without having to convert them later.  However, the interesting thing to note here is how we’re accessing the config file this time.  We can go straight to ConfigurationManager.AppSettings to read the keys and values because the only thing we are doing is reading from the file.

Nifty, eh?

That’s all I’ve got for this one.  Stay tuned for more, and don’t forget to leave a comment either here or on the forums!

Author: Tyler Sells

Github

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • More
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to email a link to a friend (Opens in new window) Email
  • Click to share on Reddit (Opens in new window) Reddit

Like this:

Like Loading...

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Follow me on Twitter

My Tweets

Github Repos

vtsells (Tyler Sells)

Tyler Sells

vtsells
http://www.nubgrammer.com
Joined on Jun 21, 2017
9 Public Repositories
100DaysOfCode
embers
MultiSelect
MVC-Project-Start
nubgrammer.com
PermIT
Spray
vtsells.github.io
Wizard
0 Public Gists

Categories

  • #100DaysOfCode (4)
  • ASP.NET (7)
  • ASP.NET Core (1)
  • ASP.NET MVC (3)
  • CSS (4)
  • General (13)
  • JS (3)
  • LESS (2)
  • Snippets (4)
  • Tools (4)
  • Tutorials (9)

Recent Posts

  • Creating a Knockout.js project on Codepen
  • 100DaysOfCode Day 3 – A State of Mind
  • 100DaysOfCode Day 2 – The Building Blocks
  • 100DaysOfCode Day 1 (Sort of cheated already)
  • Committing to #100DaysOfCode
© 2025 Nubgrammer | Powered by Superbs Personal Blog theme
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept”, you consent to the use of ALL the cookies.
Do not sell my personal information.
Cookie SettingsAccept
Manage consent

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
CookieDurationDescription
cookielawinfo-checkbox-analytics11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional11 monthsThe cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy11 monthsThe cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytics
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Advertisement
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
Others
Other uncategorized cookies are those that are being analyzed and have not been classified into a category as yet.
SAVE & ACCEPT
%d

    Privacy Policy