Some ASP.NET 2.0 Configuration Tips


By Peter Bromberg
Printer Friendly Version
View My Articles

  

Illustrates some common techniques for managing web.config sections across multiple deployments and modes for ASP.NET 2.0 Web applications.



 It is a common scenario for ASP.NET Web developers to want to have different sets of configuration data depending on whether the project is being developed locally within Visual Studio in Debug mode, being tested in QA in Release mode, or is in Release mode in production. Also, settings may differ from machine to machine if the Application is deployed into a web farm scenario.

 There are several ways to enhance the ability to maintain separate sets of configuration data; the typical environment is one where we have a number of settings in the web.config that will rarely be changed, and some others that we do want to be able to have changes based on what mode and what location the application is being run from.

 The simplest technique, and one that is workable in a majority of scenarios, is to use the "file=" attribute of the appSettings section:

<appSettings file="myCustomAppSettings.config" >
   <add key="one" value="this will be overwritten by the same key in the external file" />
  </appSettings>

  //(myCustomAppSettings.config file:)

<appSettings>
<add key="one" value="this will replace the key in the main web.config with the same name" />
  <add key="two" value="this is from the external file" />
</appSettings>
Note that the root element of the external file is "<appSettings>". Any keys in this file with the same key name as one present in the main web.config appSettings section will overwrite the one in web.config. All others are simply added to the collection, which is a NameValueCollection. For example, the following snippet will write out these values to a Page:

NameValueCollection coll= ConfigurationManager.AppSettings;
    Response.Write("<b>appSettings Section:</b><BR/>");
     foreach(string key in coll.AllKeys)
         { 
             Response.Write(key +": "+coll[key] +"<br/>");
         }

Any settings in the web.config appSettings section that aren't replaced by the external definitions because of having the same key name will appear first in the collection.

With this arrangement, you can have a separate "myCustomAppSettings.config" file in each deployment, and when the web.config is deployed, this file is left alone. So, each deployment location can have one of these that will always contain different items without fear of copying a debug web.config into a production deployment and destroying required items and values.


Other standard sections can also be read directly from web.config with the use of an external file. For these you would use the configSource attribute:

<connectionStrings configSource="externConnectionStrings.config" />

//(externConnectionStrings.config file:)
<connectionStrings>
 <add name="conn1" connectionString="Note that the localSqlServer shows up because it is defined in web.config (machine.config) and we did not use the clear or remove directives" providerName="SqlClient" />
</connectionStrings>
Note that in this case the root element of the external file must be the name of the standard section that's being imported - in this case, "connectionStrings".
You will see that because we did not use the <clear /> or <remove name="localSqlServer" /> elements, the list that is output will include this connection string as the first  item in the ConnectionStringSettingsCollection that is output. That is because it is predefined in the master web.config file in the .NET Framework directory:


ConnectionStringSettingsCollection cnColl = ConfigurationManager.ConnectionStrings;
    foreach(ConnectionStringSettings set in cnColl)
        {
            Response.Write(set.Name + ": "+set.ConnectionString +"<br/>");
        }

Finally, you can create a custom configuration "appSettings" section of your choice using the System.Configuration.AppSettingsSection class:

In the web.config:

<configSections>
      <section name ="states" type="System.Configuration.AppSettingsSection,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> 
</configSections> <states file="states.config" > <add key="Arizona" value="AZ" /> </states> <system.web> ...
In the "states.config" external file:

<states>
<add key="New York" value ="NY" />
<add key="Massachusetts" value="MA" />
</states>
The elements are combined at runtime, with the one(s) in the web.config appearing first in the collection. Here is an example of reading the above section:

string configPath = HttpContext.Current.Request.CurrentExecutionFilePath;
  configPath = configPath.Substring(0, configPath.LastIndexOf('/'));
      if (configPath.Length == 0) configPath = "/";
         Configuration myRootConfig = WebConfigurationManager.OpenWebConfiguration(configPath);
         AppSettingsSection myAppSettings = myRootConfig.GetSection("states") as AppSettingsSection;
         KeyValueConfigurationCollection myColl = myAppSettings.Settings;
         foreach(KeyValueConfigurationElement elem in myColl)
            {
                Response.Write(elem.Key +": "+elem.Value +"<br/>");
            }

Note that with this arrangement, it is possible to have multiple web.config files at various locations on the filesystem. Provided that the correct path is supplied to the configPath variable as above, that is the web.config that will be loaded and processed.  This provides for a lot more "custom" flexibility at the expense of a bit more complicated code.

The WebConfigurationManager class in the System.Web.Configuration namespace is the main programming point that allows for custom manipulation of configuration data. It includes static methods to retrieve application settings and connection strings.  It works much like the ConfigurationManager class but is oriented toward web applications.


The GetSection static method takes an XPath expression to indicate the section you want to get, and allows you to cast the resulting object to a strongly typed reference for built-in section types.  For example, here is how one can read the <identity... section:

IdentitySection section;
 section = WebConfigurationManager.GetSection("system.web/identity") as IdentitySection;
    if (section != null)
    {
       Response.Write("Identity: Impersonate = " + section.Impersonate);
    }
The output page from the sample app should look like this:

appSettings Section:
one: this will replace the key in the main web.config with the same name
two: this is from the external file

connectionStrings Section:
LocalSqlServer: data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true
conn1: Note that the localSqlServer shows up because it is defined in web.config (machine.config) and we did not use the clear or remove directives

Custom appSettings Section (states):
Arizona: AZ
New York: NY
Massachusetts: MA

Identity Section (via GetSection):
Identity: Impersonate = True


Using the classes in the Configuration namespace, developers have all the tools needed to programmatically create, read, edit and save web.config and related configuration files. There is almost never a need to, nor would it be advisable to "roll your own", unless you are creating custom configuration files  -- all you need to do is study and learn to use the existing API.

If you want to see an advanced use of this concept, download the Enterprise Library 3.1 and look at how the custom sections and their respective classes are created and modified for the various parts of the Library.

Finally, if you create external configuration "include" files, it is a good idea to give them the ".config" extension. Files with this extension are never served by IIS under ASP.NET.  And one final tip: an easy way to get the assembly metadata string for the creation of a configSection element is to load the assembly via Reflector. The entire string will appear at the bottom of the main window when the loaded assembly is selected in the tree list, and you can copy it to the clipboard. Let me tell you, if Google is your friend for finding stuff on the web, Reflector is your friend for finding stuff in the .NET Framework.

The downloadable Visual Studio 2005 Web Application Project will illustrate all of the above.


Biography
Peter Bromberg is a C# MVP, MCP, and .NET expert who has worked in banking ,financial and telephony for 20 years. Pete focuses exclusively on the .NET Platform, and his samples at GotDotNet.com have been downloaded over 56,000 times. Peter enjoys producing 3D raytraced digital photo collage with Maya, the beach, and fine wines. You can view Peter's UnBlog and IttyUrl sites.
Please post questions at forums, not via email!

button
 
Article Discussion: Some ASP.NET 2.0 Configuration Tips
Peter Bromberg posted at 17-Jun-07 04:08
Original Article

promotion
Silverlight    WPF    WCF    WWF    LINQ   
JavaScript    AJAX    ASP.NET    XAML   
C#    VB.NET    VB 6.0    GDI+    IIS    XML   
.NET Generics    Anonymous Methods    Delegate   
Visual Studio .NET    Expression Blend    Virus   
Windows Vista    Windows XP    Windows Update   
Windows 2003 Server    Windows 2008 Server   
SQL Server    Microsoft Excel    Microsoft Word   
SharePoint    BizTalk    Virtual Earth   
.NET Compact Framework    Web Service   

"Everything" RSS / ATOM Feed Parser
How to send and receive messages through message queuing in .Net
How to Read text file as database
SQL Server 2005 Paging Performance Tip
Display code of web page.
Fully Scalable Excel File Importer class for .net using Microsoft Jet driver
Generic Chart Color Manager class that can be used for any charts
Helper class to style the infragistics wingrid
Using Reflection to detemine as Assembly Info in and out.
Helper class to play with Window (Owners and position)
Resolving displayname from the culture using the XmlLanguage and LanguageSpecificStringDictionary class
Manipulate file attributes in VB.NET
Forms Based Authentication Filtered Content Editor for SharePoint
How to create a Tree View of the Windows Folder and extract all the file-folder info.
How to use AssemblyInfo.cs file in win forms to provide much needed information on Assemblies
Sorting In Datagrid
Helper class to work with NativeMethods in the native api's
Silverlight Line Of Business Applications With Offline WPF Versions
C# : Database monitoring system using XML file
C# : Adding ComboBox to ListView SubItem
Sum of Numbers Captcha: Keeping it Simple
C# Create a Piechart for the specified Hard Disk Drive Utilization
Extension Methods for DataSet and DataTable that makes tasks easier
Accessing IIS Hosted WCF Services from PHP
Helper class that provides most commonly used Extension Methods for DateTime object
Helper class to work with a Status Bar in WPF.
Finding Unmatched Records in Dataset Tables Using Linq
Silverlight Toolkit: Autocomplete TextBox Stock Symbols and Chart
COOL Auto Complete textbox using javascript
Creating a Serializable Log Entry for Microsoft Enterprise Library to log to a Database
ASP.NET Searching Values in Datagrid