Hi Jonathan:
By far the easiest thing for you to do is to retrieve (read-only) simple
name/palue pairs from App.config (or Web.config).
Here is a working sample (works with <appSettings> in App.config; slight
tweaking for Web.config):
/*******************************************************************/
// You must first set a project reference to System.Configuration.dll
// the following is the App.config file contents
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="customsetting1" value="Some text here"/>
<add key="customsetting2" value="Some other text here"/>
</appSettings>
</configuration>
//Here is the C# code that reads the above:
string theKey = string.Empty;
string theValue = string.Empty;
System.Configuration.Configuration appConfig =
System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
System.Configuration.KeyValueConfigurationElement customSetting =
appConfig.AppSettings.Settings["customsetting1"];
foreach (System.Configuration.KeyValueConfigurationElement currentElement in
appConfig.AppSettings.Settings)
{
theKey = currentElement.Key;
theValue = currentElement.Value;
}
/*******************************************************************/
The above technique would work for a <connectionStrings /> element:
ConnectionStrings and AppSettings are fully implemented for you by
System.Configuration types. You just use them "out of the box" (one
technique is that which I posted above; others are available).
Notes:
1. you cannot programmatically *write* to the <appSettings> or
<connectionString> elements.
2. If you want to programmatically write (in addition to reading), then you
have to go the more complex route presented in the links I gave earlier and
discussed below.
3. If you want your own custom configuration sections (beyond <appSettings>
and <connectionStrings>), then you have to go a far more complex route:
4. You will need a <configSections> element. It MUST MUST MUST be the very
first element within the opening <configuration> element. Everything will
choke if you have a <configSections> element that is, for example, located
below your <appSettings> element.
Don't forget this. You'll get the most vague "configuration system failed to
initialize" exception and NOTHING will work. Everything looks right - in
terms of syntax in both C# and App.config. But the whole freaking problem is
that your <configSections> section is just in the wrong *sequence* (not
depth) in App.config. That's just stupid. Anyway....
2. Suppose you need something even *slightly* more complex than a simple
name/value pairs available in <appSettings> and <connectionStrings>,
something like the following:
<MyCustomSection logExceptions="true" logProgress="true">
<WebSites>
<WebSite domainName="Site1.com" webServer="ServerName1" />
<WebSite domainName="Site2.com" webServer="ServerName1" />
<WebSite domainName="Site3.com" webServer="ServerName2" />
</WebSites>
</MyCustomSection>
If you want to programmatically read that, then you will need to create one
or more classes - yes write a bunch of code - to get your application to
recognize those sections.
In a nut shell, your classes EXTEND various System.Configuration types. At
the end of the effortwhat you have, and this is great, is a runtime object
that represents, from the example above, MyCustomSection. Your custom object
woudl have a strongly typed collection of WebSite objects and properties for
all of the attributes. Specifically, MyCustomSection would be your custom
type. It would have two boolean properties (one for each of the attributes:
logExceptions and logProgress); and a third property that exposes a strongly
typed collection of WebSite objects. Each WebSite object would, in turn,
have two string properties (one for each of the WebSite attributes,
domainName and webServer).
YES - this is a whole lot of work. But at the end of the day you have a
strongly typed collection of what-ever-it-is-that-you-want. The
System.Configuration types that you extend take care of all of the "heavy
lifting" of parsing the .config file as an XML document. You don't have to
worry about any of that. So that is the good news.
The bad news is that there is practically zero guidance on how to extend the
types in System.Configuration in a particular way so as to correctly work
with the custom XML structure you need or want.
So I'd suggest you do one of these:
1. Stay with the <appSettings> and <connectionStrings> sections - provided
that you can live with read-only name/value pairs.
2. If #1 is inadequate, then budget some time to go up the learning curve on
this unintuitive process of decyphering System.Configuration. The best
learning aid I've found are those articles I noted earlier.
Finally - I hope I'm wrong about all of the above and somehow failed to
locate some treasure trove of helpful documentation other than that which I
already pointed out. I doubt I've missed anything though - given the extent
of searching I undertook last week. Remember, practically all of the
"how-tos" and "recipes" for working with custom configuration data that
you'll find on the Web all work with the now depracated
ConfigurationSettings type. The few recipes for using the new
System.Configuration types offer practically zero perspective, and straying
from their sample XML structure results in nothing working.
HTH
- "Smithers"
Jonathan Wood said:
Thanks Smithers for the detailed response. I've found most of the
descriptions for properties and methods in the .NET documentation are
pathetically unhelpful and make sense only when you already understand
what the property or method does.
The articles look fairly long and will take careful reading if I am to
fully understand everything they say. I've saved your post and will read
them if I have to. But I really wish someone would post a simple
example--that would be so easy for me. Perhaps others are having trouble
with this as well.
Thanks again.
--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com
Smithers said:
I can't understand why Microsoft would provide surprisingly little
guidance on how to use the types in the System.Configuration namespace.
It's been around for a couple of years now and it's not nearly as
straight-forward as the MSDN documentation makes it seem at first glance.
Having a few comments with each type's members isn't helpful in this case.
Jon Rista (author of the code project articles below) should be given some
award for his work which compensates for MS falling flat on its face on
this one.
The first of the following 3 articles is the most practical and helpful
if you want to understand how to make use of the new System.Configuration
types. The other articles offer additional insight (all by Jon Rista -
some guy who has spent a huge amount of time figuring it all out).
http://www.codeproject.com/dotnet/mysteriesofconfiguration.asp
http://www.codeproject.com/dotnet/mysteriesofconfiguration2.asp
http://www.codeproject.com/csharp/mysteriesofconfiguration3.asp
A couple of tips that might be useful:
1. googling this topic is especially USELESS because so much of what's
out there talks about the [now deprecated] ConfigurationSettings type
(from 1.0 and 1.1). Whenever you see something that is based on
ConfigurationSettings you have to ignore it and keep looking.
2. The whole point of the new configuration management system (it appears
to me, anyway), is to provide us with strongly typed objects that
maintain our configuration settings. So rather than thinking of
App.config or Web.config as simply an XML layout for your configuration
settings (it is that, too) - think about App.config simply as a
serialized version of your application-specific configuration objects.
3. If point #2 is maddening ("geeze I just want to store and read a
simple custom collection of xml nodes"), then go ahead and either (1) use
the new stuff only for the built-in AppSettings and ConnectionStrings
sections (which are exposed natively); or (2) revert to the old school
ConfigurationSettings way of doing things.
-HTH
Jonathan Wood said:
This is crazy. Does anyone have a simple example of reading a variable
from the application config file for a desktop application?
I've spent way too much time on this. I've found huge examples and lots
of help topics. But the .NET help topics are beyond poor. And that makes
it difficult for me to completely understand huge examples. And the
smaller examples I've managed to find don't work.
Since I want to get my application to do a few things in addition to
reading and writing the settings, I'd prefer to find a simple example
and be able to move on.
Has anyone out there cracked ConfigurationManager for a desktop app?
Thanks.