Evjen c31.tex V2 - 01/28/2008 4:01pm Page 1445
Chapter 31: Configuration
config.ConnectionStrings.ConnectionStrings.Add(newConnSetting)
’ Save the changes
config.Save()
Catch cEx As ConfigurationErrorsException
lblStatus.Text = "Status: " + cEx.ToString()
Catch ex As System.UnauthorizedAccessException
’ The ASP.NET process account must have read/write access to the directory
lblStatus.Text = "Status: " + "The ASP.NET process account must have
read/write access to the directory"
Catch eEx As Exception
lblStatus.Text = "Status: " + eEx.ToString()
End Try
ShowConnectionStrings()
End Sub
C#
protected void Button1_Click(object sender, EventArgs e)
{
// Get the file path for the current web request
string webPath = Request.ApplicationPath;
// Get configuration object of the current web request
Configuration config =
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(webPath);
// Create new connection setting from text boxes
ConnectionStringSettings newConnSetting = new
ConnectionStringSettings(txtName.Text, txtValue.Text, txtProvider.Text);
try
{
// Add the connection string to the collection
config.ConnectionStrings.ConnectionStrings.Add(newConnSetting);
// Save the changes
config.Save();
}
catch (ConfigurationErrorsException cEx)
{
lblStatus.Text = "Status: " + cEx.ToString();
}
catch (System.UnauthorizedAccessException uEx)
{
// The ASP.NET process account must have read/write access to the directory
lblStatus.Text = "Status: " + "The ASP.NET process account must have" +
"read/write access to the directory";
}
catch (Exception eEx)
{
lblStatus.Text = "Status: " + eEx.ToString();
}
// Reload the connection strings in the list box
ShowConnectionStrings();
}
1445
Evjen c31.tex V2 - 01/28/2008 4:01pm Page 1446
Chapter 31: Configuration
Manipulating a machine.config File
The
OpenMachineConfiguration
method of the
System.Configuration.ConfigurationManager
class
provides a way to manipulate the
machine.config
file. The
OpenMachineConfiguration
method is a
static method.
Listing 31-36 shows a simple example that enumerates all the section groups stored in the
machine
.config
file. As shown in this listing, you’re getting an instance of the configuration object using the
OpenMachineConfiguration
method. Then you are binding the
SectionGroups
collection with the Grid-
View control.
Listing 31-36: Configuration groups from machine.config
VB
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs)
’ List all the SectionGroups in machine.config file
Dim configSetting As Configuration = _
System.Configuration.ConfigurationManager.OpenMachineConfiguration()
GridView1.DataSource = configSetting.SectionGroups
GridView1.DataBind()
End Sub
C#
protected void Button2_Click(object sender, EventArgs e)
{
// List all the SectionGroups in machine.config file
Configuration configSetting =
System.Configuration.ConfigurationManager.OpenMachineConfiguration();
GridView1.DataSource = configSetting.SectionGroups;
GridView1.DataBind();
}
In the same way, you can list all the configuration sections using the
Sections
collections, as shown in
Listing 31-37.
Listing 31-37: Configuration sections from machine.config
VB
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs)
’ List all the SectionGroups in machine.config file
Dim configSetting As Configuration = _
System.Configuration.ConfigurationManager.OpenMachineConfiguration()
GridView1.DataSource = configSetting.Sections
GridView1.DataBind()
End Sub
C#
protected void Button2_Click(object sender, EventArgs e)
{
// List all the SectionGroups in machine.config file
Configuration configSetting =
System.Configuration.ConfigurationManager.OpenMachineConfiguration();
1446
Evjen c31.tex V2 - 01/28/2008 4:01pm Page 1447
Chapter 31: Configuration
GridView1.DataSource = configSetting.Sections;
GridView1.DataBind();
}
Manipulating web.config from Remote Servers
The ASP.NET Management Objects also provide a way to read configuration information from remote
servers.
For example, if you would like to manipulate the Expense Web application’s configuration file located
on the imaginary
Optra.Microsoft.com
site, you can do so as shown in Listing 31-38.
Listing 31-38: Manipulating a remote server’s web.config
VB
’ Connect to the web application Expense on Optra.Microsoft.com server
Dim configSetting As Configuration = _
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration _
("/Expense", "1", "Optra.Microsoft.com")
Dim section As System.Configuration.ConfigurationSection = _
configSetting.GetSection("appSettings")
Dim element As KeyValueConfigurationElement = _
CType(configSetting.AppSettings.Settings("keySection"), _
KeyValueConfigurationElement)
If Not element Is Nothing Then
Dim value As String = "New Value"
element.Value = value
Try
config.Save()
Catch ex As Exception
Response.Write(ex.Message)
End Try
End If
C#
// Connect to the web application Expense on Optra.Microsoft.com server
Configuration configSetting =
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration
("/Expense", "1", "Optra.Microsoft.com");
ConfigurationSection section = configSetting.GetSection("appSettings");
KeyValueConfigurationElement element =
configSetting.AppSettings.Settings["keySection"];
if (element != null)
{
string value = "New Value";
element.Value = value;
Continued
1447
Evjen c31.tex V2 - 01/28/2008 4:01pm Page 1448
Chapter 31: Configuration
try
{
configSetting.Save();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
The code in Listing 31-38 demonstrates how to give the machine address in the constructor method to
connect to the remote server. Then you change a particular
appSettings
section to a new value and save
the changes.
Protecting Configuration Settings
When ASP.NET 1.0 was introduced, all the configuration information was stored in human-readable,
clear-text format. However, ASP.NET 1.1 introduced a way to store the configuration information inside
the registry using the Data Protection API (or DPAPI).
For example, Listing 31-39 shows how you can store a process model section’s username and password
information inside the registry.
Listing 31-39: Storing the username and password in the registry and then referencing
these settings in the machine.config
<
processModel
userName="registry:HKLM
\
SOFTWARE
\
ExampleApp
\
Identity
\
ASPNET_SETREG,userName"
password="registry:HKLM
\
SOFTWARE
\
ExampleApp
\
Identity
\
ASPNET_SETREG,password"
/
>
ASP.NET 1.0 also acquired this functionality as a fix. Visit the f ollowing URL for more information:
= kb;en-us;329290
.
ASP.NET 3.5 includes a system for protecting sensitive data stored in the configuration system. It uses
industry-standard XML encryption to encrypt specified sections of configuration that contain any sensi-
tive data.
Developers often feel apprehensive about sticking sensitive items such as connection strings, passwords,
and more in the
web.config
file. For this reason, ASP.NET makes it possible to store these items in
a format that is not readable by any human or machine process without intimate knowledge of the
encryption techniques and keys used in the encryption process.
One of the most encrypted items in the web.config is the
<
connectionStrings
> section. Listing 31-40
shows an example of a
web.config
filewithanexposedconnectionstring.
Listing 31-40: A standard connection string exposed in the web.config file
<
?xml version="1.0"?
>
<
configuration
>
1448
Evjen c31.tex V2 - 01/28/2008 4:01pm Page 1449
Chapter 31: Configuration
<
appSettings/
>
<
connectionStrings
>
<
add name="Northwind"
connectionString="Server=localhost;Integrated Security=True;Database=Northwind"
providerName="System.Data.SqlClient" /
>
<
/connectionStrings
>
<
system.web
>
<
compilation debug="false" /
>
<
authentication mode="Forms"
>
<
forms name="Wrox" loginUrl="Login.aspx" path="/"
>
<
credentials passwordFormat="Clear"
>
<
user name="BillEvjen" password="Bubbles" /
>
<
/credentials
>
<
/forms
>
<
/authentication
>
<
/system.web
>
<
/configuration
>
In this case, you might want to encrypt this connection string to the database. To accomplish this, the
install of ASP.NET provides a tool called aspnet_regiis.exe. You find this tool at
C:
\
WINDOWS
\
Microsoft.NET
\
Framework
\
v2.0.50727
. To use this tool to encrypt the <connectionStrings> section,
open a command prompt and navigate to the specified folder using
cd C:
\
WINDOWS
\
Microsoft.NET
\
Framework
\
v2.0.50727
. Another option is to just open the Visual Studio 2008 Command Prompt. After
you are in one of these environments, you use the syntax presented in Listing 31-41 to encrypt the
<
connectionStrings
> section.
Listing 31-41: Encrypting the <connectionString> section
aspnet_regiis –pe "connectionString" –app "/EncryptionExample"
Running this bit of script produces the results presented in Figure 31-6.
Looking over the script used in the encryption process, you can see that the
–pe
command specifies the
section in the
web.config
file to encrypt, whereas the
–app
command specifies which application to
actually work with. If you look back at the
web.config
file and examine the encryption that occurred,
you see something similar to the code in Listing 31-42.
Listing 31-42: The encrypted <connectionStrings> section of the web.config
<
?xml version="1.0"?
>
<
configuration
>
<
appSettings/
>
<
connectionStrings
Continued
1449
Evjen c31.tex V2 - 01/28/2008 4:01pm Page 1450
Chapter 31: Configuration
configProtectionProvider="RsaProtectedConfigurationProvider"
>
<
EncryptedData Type=" />xmlns=" />>
<
EncryptionMethod
Algorithm=" /
>
<
KeyInfo xmlns=" />>
<
EncryptedKey xmlns=" />>
<
EncryptionMethod
Algorithm=" /
>
<
KeyInfo xmlns=" />>
<
KeyName
>
Rsa Key
<
/KeyName
>
<
/KeyInfo
>
<
CipherData
>
<
CipherValue
>
0s99STuGx+CdDXmWaOVc0prBFA65
Yub0VxDS7nOSQ79AAYcxKG7Alq1o
M2BqZGSmElc7c4w93qgZn0CNN
VHGhDLE1OjHPV942HaYhcddK5
5XY5j7L3WSEJFj68E2Ng9+EjU
o+oAGJVhCAuG8owQBaQ2Bri3+
tfUB/Q8LpOW4kP8=
<
/CipherValue
>
<
/CipherData
>
<
/EncryptedKey
>
<
/KeyInfo
>
<
CipherData
>
<
CipherValue
>
O3/PtxajkdVD/5TLGddc1/
C8cg8RFYl8MiRXh71h4ls=
<
/CipherValue
>
<
/CipherData
>
<
/EncryptedData
>
<
/connectionStrings
>
<
system.web
>
<
compilation debug="false" /
>
<
authentication mode="Forms"
>
<
forms name="Wrox" loginUrl="Login.aspx" path="/"
>
<
credentials passwordFormat="Clear"
>
<
user name="BillEvjen" password="Bubbles" /
>
<
/credentials
>
<
/forms
>
<
/authentication
>
<
/system.web
>
<
/configuration
>
Now when you work with a connection string in your ASP.NET application, ASP.NET itself automati-
cally decrypts this section in order to utilize the values stored. Looking at the
web.config
file, you can
see a subsection within the
<
system.web
> section that exposes a username and password as clear text.
This is also something that you might want to encrypt in order to keep it away from prying eyes. Because
it is a subsection, you use the script presented in Listing 31-43.
1450
Evjen c31.tex V2 - 01/28/2008 4:01pm Page 1451
Chapter 31: Configuration
Figure 31-6
Listing 31-43: Encrypting the <authentication> section
aspnet_regiis –pe "system.web/authentication" –app "/EncryptionExample"
This code gives you the partial results presented in Listing 31-44.
Listing 31-44: The encrypted <authentication> section of the web.config
<
authentication configProtectionProvider="RsaProtectedConfigurationProvider"
>
<
EncryptedData Type=" />xmlns=" />>
<
EncryptionMethod
Algorithm=" /
>
<
KeyInfo xmlns=" />>
<
EncryptedKey xmlns=" />>
<
EncryptionMethod
Algorithm=" /
>
<
KeyInfo xmlns=" />>
<
KeyName
>
Rsa Key
<
/KeyName
>
<
/KeyInfo
>
<
CipherData
>
<
CipherValue
>
GzTlMc89r3ees9EoMedFQrLo3FI5p3JJ9DMONWe
ASIww89UADkihLpmzCUPa3YtiCfKXpodr3Xt3RI
4zpveulZs5gIZUoX8aCl48U89dajudJn7eoJqai
m6wuXTGI5XrUWTgYdELCcFCloW1c+eGMRBZpNi9
cir4xkkh2SsHBDE=
<
/CipherValue
>
<
/CipherData
>
<
/EncryptedKey
>
Continued
1451
Evjen c31.tex V2 - 01/28/2008 4:01pm Page 1452
Chapter 31: Configuration
<
/KeyInfo
>
<
CipherData
>
<
CipherValue
>
3MpRm+Xs+x5YsndH20lZau8/t+3RuaGv5+nTFoRXaV
tweKdgrAVeB+PXnTjydq/u4LBXKMKmHzaBtxrqEHRD
mNZgigLWVtfIRQ6P8cgBwtdIFhFmjm3B4tg/rA8dpJ
ivDav2kDPp+SZ6yZ9LJzhBIe9TdJvwBQ9gJTGNVRft
QOvdvH8c4KwYfiwZa9WCqys9WOZmw6g1a5jdW3hM//
jiMizY1MwCECVh+T+y+f/vpP0xCkoKT9GGgHRMMrQd
PqHUd5s7rUYp1ijQgrh1oPIXr6mx/XtzdXV8bQiEsg
CLhsqphoVVwxkvmUKEmDQdOzdrB4sqmKgoHR3wCPyB
npH58g==
<
/CipherValue
>
<
/CipherData
>
<
/EncryptedData
>
<
/authentication
>
After you have sections of your
web.config
file encrypted, you need a process to decrypt these sections
to their original unencrypted values. To accomplish this task, you use the aspnet_regiis tool illustrated in
Listing 31-45.
Listing 31-45: Decrypting the <connectionStrings> section in the web.config file
aspnet_regiis –pd "connectionString" –app "/EncryptionExample"
Running this script returns the encrypted values to original values.
Editing Configuration Files
So far in this chapter, you have learned about configuration files and what each configuration entry
means. Even though the configuration entries are in an easy, human-readable XML format, editing these
entries can be cumbersome. To help with editing, Microsoft ships three tools:
❑ Visual Studio 2008 IDE
❑ Web Site Administration Tool
❑ ASP.NET Snap-In for IIS 6.0 or Windows Vista’s Internet Information Services (IIS) Manager
One of the nice capabilities of the Visual Studio 2008 IDE is that it supports IntelliSense-based editing for
configuration files, as shown in Figure 31-7.
The Visual Studio 2008 IDE also supports XML element syntax checking, as shown in Figure 31-8.
XML element syntax checking and IntelliSense for XML elements are accomplished using the XSD-based
XML validation feature available for all the XML files inside Visual Studio 2008. The configuration XSD
file is located at
<
drive
>
:
\
Program Files
\
Microsoft Visual Studio 9.0
\
Xml
\
Schemas
\
DotNetConfig.xsd
.
The Visual Studio 2008 IDE also adds two new useful features via the XML toolbar options that can help
you with formatting the configuration settings:
❑ Reformat Selection: This option reformats the current XML notes content.
❑ Format t he whole document: This option formats the entire XML document.
1452
Evjen c31.tex V2 - 01/28/2008 4:01pm Page 1453
Chapter 31: Configuration
Figure 31-7
The Web Site Administration Tool and the ASP.NET Snap-In for IIS 6.0 or Window Vista’s IIS Man-
ager allow you to edit the configuration entries without knowing the XML element names and their
corresponding values. Chapter 24 covers these tools in more detail.
Creating Custom Sections
In addition to using the
web.config
file as discussed, you can also extend it and add your own custom
sections to the file that your can make use of just as the other sections.
One way of creating custom sections is to use some built-in handlers that enable you to read key-value
pairs from the
.config
file. All three of the following handlers are from the
System.Configuration
namespace:
❑
NameValueFileSectionHandler
: This handler works with the current <
appSettings
> section of
the
web.config
file. You are able to use this handler to create new sections of the configuration
file that behave in the same manner as the
<
appSettings
> section.
❑
DictionarySectionHandler
: This handler works with a dictionary collection of key-value pairs.
❑
SingleTagSectionHandler
: This handler works from a single element in the configuration file
and allows you to read key-value pairs that are contained as attributes and values.
1453
Evjen c31.tex V2 - 01/28/2008 4:01pm Page 1454
Chapter 31: Configuration
Figure 31-8
Next, this chapter looks at each of these handlers and some programmatic ways to customize the config-
uration file.
Using the NameValueFileSectionHandler Object
If youare looking to create a custom section that behaves like the <
appSettings
> section of the
web.config
file, then using this handler is the way to go. Above the <
system.web
> section of the
web.config
file, make
a reference to the
NameValueFileSectionHandler
object, along with the other default references you will
find in an ASP.NET 3.5 application. This additional reference is shown in Listing 31-46.
Listing 31-46: Creating your own custom section of key-value pairs in the web.config
<
configSections
>
<
section name="MyCompanyAppSettings"
type="System.Configuration.NameValueFileSectionHandler, System,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
restartOnExternalChanges="false" /
>
<
sectionGroup name="system.web.extensions"
type="System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"
>
<
sectionGroup name="scripting"
type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
>
<
section name="scriptResourceHandler"
type="System.Web.Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"
1454