It's great to be able to put settings in the Web.Config file for my ASP.NET projects. The problem for me, though, is that when I use
System.Configuration.ConfigurationSettings.AppSettings(name)
to return a setting that doesn't exist in the file, an empty string ("") is returned, when ideally I would like an exception to let me know that something is missing or mispelled in my config file (or application code). A lot of times, that empty string will cause errors or other odd behavior that can be tough to detect. This happened to me the other day where I spent hours trying to figure out why the heck something simple wasn't working, when I realized it was because one of the setting names was spelled wrong in the config file. Also, string values are always returned which often need to be cast to the proper datatype.
For these reasons, I have found it very handy to instead access your web.config AppSettings through a couple of functions, such as these:
Public Function GetSetting(ByVal Name As String) As String
Dim s As String = System.Configuration.ConfigurationSettings.AppSettings(Name)
If s = "" Then
Throw New Exception("Error: App Setting not found: " & Name)
Else
Return s
End If
End Function
Public Function GetSettingInt(ByVal Name As String) As Integer
Return Convert.ToInt32(Setting(name))
End Function
This way, at runtime you get an exception when you ask for a setting that doesn't exist in your file. In addition, multiple versions of this function allow you to avoid the need to cast those string values to other datatypes.
For this to work, of course, you must be sure that you don't need to store empty strings in your Web.Config file. If you do, you might come up with a standard such as "N/A" or something, and then have this function convert that value to an empty string when returning the result.
Run-time checking is good, but of course compile-time checking is even better. Another trick you can do is to define an enumeration to represent each of your settings:
Public Enum AppSettingInt
MinFileSize
MaxFileSize
DefaultAmount
End Enum
Public Enum AppSettingStr
SMTPServer
DBConnect
EmailAddress
End Enum
You can then make your previous Setting() functions private, and then define public versions of your GetSetting() functions like this:
Public Function GetSetting(ByVal Name As AppSettingStr) As String
Return GetSetting([Enum].GetName(GetType(AppSettingStr), Name))
End Function
Public Function GetSettingInt(ByVal Name As AppSettingInt) As Integer
Return SettingInt([Enum].GetName(GetType(AppSettingInt), Name ))
End Function
The GetName() method of the [Enum] class returns a string representing the name of the enumerated value passed in.
Now, you have compile-time checking of your web.config settings. Previously, you would write:
debug.WriteLine(GetSetting("SMTPServer"))
which would not return an exception until the code is executed if that key doesn't exist. But with the enumerations, you would write:
debug.WriteLine(GetSetting(SMTPServer))
which returns a compile-time error if that setting doesn't exist. Note the lack of quotations. In addition, you get the benefit of Intellisense when writing your code, which is useful for typo-prone guys like myself.
There is a bit more maintenance needed for this approach -- you would have to add values to your enumerations whenever you add them in your Web.Config file. But I feel it is well worth it.
Finally, you can also do things like storing different settings depending on the HostName of the web application as well, and use this global function to determine which value to pull from the web config. For example, you might have 3 different database connection strings for your different environments (dev, staging, prod) and you could do something like this:
<add key="dbconn-productiondomain.com" value=" ...."/>
<add key="dbconn-10.10.1.39" value=".." />
<add key="dbconn-localhost" value="..." />
where "productiondomain.com" is your production host name, "10.10.1.39" is your staging server's IP, and "localhost" is of course your local development box. By accessing settings through helper functions, you can create a function that pulls the right setting for "dbconn" depending on the host that is running the web application and you only have to maintain 1 web.config file and not worry about the differences between your different environments.
Well, those are just some ideas and some of the things I have found useful in ASP.NET 1.1. I have just begun to really explore and work with ASP.NET 2.0, so I am not fully aware of all the configuration differences and possibilities there, but I suspect that lots of this may apply in that environment as well.
Any other tricks or advice for working with configuration settings? Or, have I re-invented the wheel here?
see also: