Creating a Type Safe AppSettings Accessor for ASP.NET

Categories: ASP.NET MVC

Many times I place settings in the <appSettings> section of the web.config file for an ASP.NET application.  These settings could be things like the title of the application, a URL for support, or maybe e-mail settings if your application sends out email.  Retrieving this information involves the use of the ConfigurationManager class in the System.Configuration namespace.

One technique that I like to use is to wrap each of the settings into a type-safe read-only property accessor that is a static member on a static helper class.  The type of the property is the correct type that we expect in order to use it in code.  For example, if you have a on/off switch in your settings you probably want the value of the setting to be a bool.  Many times your settings are just strings, which are the easiest to parse but maybe you also want to ensure that the string is actually there and not null.

The following code snippet shows an implementation of a static helper class that does all these things:

public static class AppSettings
{
    /// <summary>
    /// Gets the application's title.
    /// </summary>
    public static string ApplicationTitle
    {
        get { return Retrieve("Application.Title"); }
    }

    private static string Retrieve(string key, bool required = true)
    {
        string value = ConfigurationManager.AppSettings[key];
        if (required && string.IsNullOrEmpty(value))
            throw new InvalidOperationException(
                string.Format("{0} is missing but is required to be defined in appSettings.", key));
        return value;
    }

    private static bool RetrieveBool(string key)
    {
        string s = Retrieve(key);
        bool result = false;
        if (!bool.TryParse(s, out result))
            throw new InvalidOperationException(
                string.Format("{0} is missing or has an invalid setting. " +
                                             "'true' or 'false' are acceptable values for this setting.", key));
        return result;
    }

    private static int RetrieveInt(string key)
    {
        string s = Retrieve(key);
        int result = 0;
        if (!int.TryParse(s, out result))
            throw new InvalidOperationException(
                string.Format("{0} is missing or has an invalid setting. " +
                                "An integer value was expected.", key));

        return result;
    }

    private static DateTime RetrieveDateTime(string key)
    {
        string s = Retrieve(key);
        DateTime result;
        if (!DateTime.TryParse(s, out result))
        {
            throw new InvalidOperationException(
                string.Format("{0} is missing or has an invalid setting.  A valid date/time format was expected.", key));
        }

        return result;
    }

    private static T RetrieveEnum<T>(string key) where T : struct
    {
        T result = default(T);
        if (!Enum.TryParse<T>(Retrieve(key), out result))
            throw new InvalidOperationException(string.Format("{0} is not a valid enumeration value.", key));
        return result;
    }
}


You can see that there are several private helpers that all Retrieve a particular data type given a key name.  There’s one for strings, bools, ints, date/times, and even enums.  If the wrong data type or a missing value is detected, an exception is thrown so you can catch mis-configured apps easily.

To use this class, you’d simply place in your code like so (in a Razor view, but it could be anywhere):

<h1 class='title'>@AppSettings.ApplicationTitle</h1>

No Comments