# Tuesday, 05 June 2012

The .NET Framework provides configuration files - app.config and web.config - to store application-wide configurable information.

But these are just text files, so they can be read by anyone with the proper permissions. What if I want to store sensitive information in this file, such as a password or a connection string?f

Fortunately, the .NET Framework also provides a mechanism for encrypting parts of a config file. This functionality is available in the System.Configuration namespace in the System.Configuration assembly, so you will need to set a reference to this assembly (Project | Add Reference | .NET tab) and add the following line to the top of your class file
using System.Configuration;

The ConfigurationManager.OpenExeConfiguration static method accepts the name of an assembly and returns a Configuration object that can be used to manipulate the config file. It is important to remember that, when a project is built, the project's app.config file is renamed to {AssemblyName}.exe.config and copied to the bin\Debug or bin\Release folder (depending on the build configuration). It is the {AssemblyName}.exe that is passed into the OpenExeConfiguration method and it is the config file under the bin folder that will be affected by our code.

For example, the following code creates a Configuration object to read and manipulate the config file associated with the MyAwesomeApp.exe assembly

string appName = "MyAwesomeApp.exe";
Configuration config = ConfigurationManager.OpenExeConfiguration(appName);

We can call the Configuration object's GetSection method to get a reference to a particular section of the config file. For example, if we want to work with the connectionStrings section, we use the code

var section = (ConnectionStringsSection) config.GetSection("connectionStrings");

Now we can check to see if the section is already encrypted (IsProtected property), encrypt the section (ProtectSection method), or decrypt the section (UnprotectSection method). The following code encrypts the connectionString section

string appName = "MyAwesomeApp.exe";
Configuration config = ConfigurationManager.OpenExeConfiguration(appName);
ConnectionStringsSection section = config.GetSection("connectionStrings") as ConnectionStringsSection;
if (!section.SectionInformation.IsProtected)
{
    section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
}
config.Save();


The code below decrypts the connectionString section

string appName = "MyAwesomeApp.exe";
Configuration config = ConfigurationManager.OpenExeConfiguration(appName);
ConnectionStringsSection section = config.GetSection("connectionStrings") as ConnectionStringsSection;
if (section.SectionInformation.IsProtected)
{
    //it is so we need to remove the encryption
    section.SectionInformation.UnprotectSection();
}
config.Save();

The final step is to write changes back to the file by calling the Configuration object's Save method.
config.Save();

Below is the unencrypted config file

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="MyApp_Dev" connectionString="Data Source=Server01;Initial Catalog=AwesomeDB_Dev;Integrated Security=True"/>
    <add name="MyApp_QA" connectionString="Data Source=Server01;Initial Catalog=AwesomeDB_QA;Integrated Security=True"/>
    <add name="MyApp_Prod" connectionString="Data Source=Server01;Initial Catalog=AwesomeDB;Integrated Security=True"/>
  </connectionStrings>
  <appSettings>
    <add key="CompanyName" value="The Awesome Company"/>
    <add key="CompanyPhone" value="313-555-4321"/>
  </appSettings>
</configuration>

And here is the same config file with the connectionStrings section encrypted
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
    <EncryptedData>
      <CipherData>
        <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA/NM6tBoQfE2WAlH0NVuRWQQAAAACAAAAAAAQZgAAAAEAACAAAADdZOBg8ugEiLd8RlHk95C+fuXUTC706/hDeZT2XN8G0gAAAAAOgAAAAAIAACAAAABEW5bTk3uNJDoKMt26yvD+YY1v0fqe2et8KWeJOewx3UADAADGEgVw4K4nlwQjjKpu6BZYMYXeB1eovlbYrEbg/A+Kk6UhqBTdAqt6UmW/6B4M2pXWpP9VqDTDfr7GKEK06qDdXRnYfGYH1JAg2xPoI3aeA5DQP6HAIbSymXejw/B+s47L4rTT2R4PvfRfMYiMppxCrEh+eopKdvcg34JsD+o6Il+6a4TiTiYLzQ9BESoxepfY9pqaADFrLChPYzwjymAqfsAFE/n++APjb7aktViu5+AI+QM3RDEhDFzsP7Wy+UkGsPrIoyMUaLMFNibK7LZFiBL6+VHZEur+4xyI+Uu+UH194oBOX1g77nBzuTsivNgH7048JhbzeSk9mjOZrGACX433vC6neqGaJ42sC9sC16JX9CGEZrnipeoyEeR0RT1H3A38Xasn9lYkUyE3LBIJ1k0iZJoAAnCvXfmSzXoXsHjpvmmlst3SAo24TL7WsdaVliBR/6i5N6AswTOemjvFe0Rhb5zoeGX36aI4SD71DYaLxqss1MVm5gc6CEsringGeHbFRqu/kTylA6xgr8rfL/eTcjQs2zRIUTzc4/DUSsyNIUWQ0+z+BDoR/AGTSx7v2OKp2vpmHLf7kn3DxYITlpDV6voJrbmpMx9lN3Z7DYQD4vNLczGPHpKbBCEXDHNw1E7QDrQaz38Ka4pRKnCRa/GL7X8euA82bYaJmEmUEBqhcZg3mQHR31X5tUbZ3HkvMxEUcRmJITpj29V6RKEmugkWmxl3OCJzuZ3vcUSgKnQIAJkqr3YBuZR3YJjDCo7i5EElFAcpv89rM2RtSVNC7i6KLJLsISjOgzD5CktrDjgMZLtxN6BdyljvWNj0L29APvSxd5ovxgCOKXE2UYpH3l4HgX78P82wx1vBNhO5UmqP7xdz1jTi9cGP6HHNiv8qJZjlTOO2/afnDDYt/pKJqWWTRUhJiZZipC+dQ6bBYOhMZbclROzptu0fIYwqdeDxPcXalN3kjIXW4kwblSd4TxmCO01JD9eL+MFT/PSaipj7CqaAHTnpL0n40jV4WK4EaxUTuXi0/NXBUjMFw4ZTdlEnLv1jjCKZ+r2Q1YbrrI286PATrwLDbYsVVGEefp8vBsOD7xfHmIPeYolbEOq2QAAAAHoGwcm8HT1RS0pXvgOjRR37Gy1BLfG/5xsYdZqOB9nT6xthVULhqwPlAsFwDXLfNZQLnpZiocwHDf07DeQiNK8=</CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>
  <appSettings>
    <add key="CompanyName" value="The Awesome Company"/>
    <add key="CompanyPhone" value="313-555-4321"/>
  </appSettings>
</configuration>

Here is a complete code snippet for getting a config and toggling the decryption of the connectionStrings section

string appName = "MyAwesomeApp.exe";
Configuration config = ConfigurationManager.OpenExeConfiguration(appName);
ConnectionStringsSection section = config.GetSection("connectionStrings") as ConnectionStringsSection;
if (section.SectionInformation.IsProtected)
{
    section.SectionInformation.UnprotectSection();
}
else
{
    section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
}
config.Save();

One of the nice things about using these libraries to encrypt config file sections is that we don’t need to change our code that reads the values in this section. For example, the following code

string connectionString = section.ConnectionStrings["MyApp_Dev"].ConnectionString;
.Net | C#
Tuesday, 05 June 2012 16:01:00 (GMT Daylight Time, UTC+01:00)
# Monday, 04 June 2012
Monday, 04 June 2012 15:01:00 (GMT Daylight Time, UTC+01:00)
# Sunday, 03 June 2012

If you are planning to attend Tech Ed North America or if you will be in the Orlando, FL area June 10, I recommend you check out the INETA Community Leadership Summit.

This free event will bring together leaders in the developer community to exchange ideas with one another. INETA is hosting the event at the Orlando City Hall on Sunday June 10 from noon to 5PM.

As part of the Summit, I will moderate a discussion titled "Getting Others Involved: Building a Leadership Team, Recruiting Volunteers & Growing Your Membership". This is based on my experience helping to grow the Great Lakes Area .NET User Group over the last couple years. Expect lots of interactions and a chance to listen and to share ideas. Other moderated discussion sessions will include “How to start a user group” and “Working with sponsors”.

In addition, this is a great chance to meet the INETA Board of Directors and other influencers in the development community.

The Summit is free and there is even an after-party hosted by Grape City, but you must register in advance at http://inetals2012.eventbrite.com/.

You can find more information at http://ineta.org/summit2012/.

Sunday, 03 June 2012 16:06:00 (GMT Daylight Time, UTC+01:00)
# Friday, 01 June 2012

Here is Steve Smith’s presentation on Common Design Patterns at the May 2012 Great Lakes Area .NET User Group (GANG).

Friday, 01 June 2012 16:00:00 (GMT Daylight Time, UTC+01:00)

Here is Kathleen Dollard’s presentation on .NET Framework Core Features at the April 2012 Great Lakes Area .NET User Group (GANG).

Friday, 01 June 2012 04:51:00 (GMT Daylight Time, UTC+01:00)
# Wednesday, 30 May 2012

 

In .NET applications, Connection Strings are easily stored in and retrieved from a web.config file or an app.config file. Add a <connectionStrings> section to the config file, directly within the <configuration> section. Within the <connectionStrings> section, place an <add> tag for each connection string you wish to store and retrieve. This <add> tag contains two important attributes: name and connectionString. The name attribute will be used to look up an entry, so each <add> tag should have a unique name. The connectionString attribute contains the connection string you will use to connect to a database. If your application needs to connect to a number of different data types, it is worth setting the Provider property as well. This is the name of a database provider installed on the current machine, that will allow you to connect to a database.
An example is shown below:

<configuration>
  <connectionStrings>
    <add name="MyApp_Dev" 
        connectionString="Data Source=Server01;Initial Catalog=AwesomeDB_Dev;Integrated Security=True"/> <add name="MyApp_QA"
        connectionString="Data Source=Server01;Initial Catalog=AwesomeDB_QA;Integrated Security=True"/> <add name="MyApp_Prod"
        connectionString="Data Source=Server01;Initial Catalog=AwesomeDB;Integrated Security=True"/> </connectionStrings> </configuration>

To retrieve a connection string by its associated name attribute, use the utilities found in the System.Configuration namespace of the System.Configuration assembly. First, set a reference to System.Assembly by selecting the menu option Project | Add Reference, selecting the System.Assembly in the Component Name column of the .NET tab of the Add Reference dialog; and, clicking the OK button. Then, add the following using statement to the top of your class file.

This namespace contains the static ConfigurationManager class, which exposes a number of methods for retrieving configuration information. ConfigurationManager.ConnectionStrings returns a collection containing all connection strings settings in the config file of the current assembly. Once we have this collection, we can retrieve a single item by specifying its name. Doing so returns a ConnectionStringSettings object that contains properties retrieved from a single <add> element of the config file. The important property is ConnectionString, which can be used with ADO.NET to connect to a database. Knowing the Provider property may also be useful if your application connects to different types of data.
Sample code is below.

ConnectionStringSettingsCollection cssCollection =
    ConfigurationManager.ConnectionStrings;
ConnectionStringSettings devCsSettings = cssCollection["MyApp_Dev"];
string devCs = devCsSettings.ConnectionString;
Wednesday, 30 May 2012 17:21:00 (GMT Daylight Time, UTC+01:00)
# Monday, 28 May 2012
Monday, 28 May 2012 22:34:00 (GMT Daylight Time, UTC+01:00)
# Friday, 25 May 2012

An App.config file or a Web.config file are great places to store configurable information – information that generally doesn’t change; but we want to be able to change easily (i.e., without rebuilding and redeploying the application.) Examples include connection strings (stored in the config file’s <connectionStrings> section) and application-wide name-value pairs (stored in the config file’s <appSettings> section).

We can add more flexibility by moving a section to an external file and linking to that file from the config file.

By splitting the file, we can manage and deploy only those settings separate from the rest of the configuration.

To do so, we create a new text file and copy that section into that file; then use the configSource attribute of the section tag in the original config file to point to the new file.

For example, the following app.config contains all the application’s connection strings and application settings

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="MyApp_Dev" connectionString="Data Source=SQL071;Initial Catalog=Awesome_Dev;Integrated Security=True"/>
    <add name="MyApp_QA" connectionString="Data Source=SQL071;Initial Catalog=Awesome_Dev;Integrated Security=True"/>
    <add name="MyApp_Prod" connectionString="Data Source=SQL071;Initial Catalog=Awesome_Dev;Integrated Security=True"/>
  </connectionStrings>
  <appSettings>
    <add key="CompanyName" value="The Awesome Company"/>
    <add key="PhoneNumber" value="(513) 555-4444"/>
  </appSettings>
</configuration>

We can accomplish the same functionality as the above app.config by creating 2 files: connections.config and appSettings.config and adding the following code to each file, respectively

connections.config:

<connectionStrings>
  <add name="MyApp_Dev" connectionString="Data Source=SQL071;Initial Catalog=Awesome_Dev;Integrated Security=True"/>
  <add name="MyApp_QA" connectionString="Data Source=SQL071;Initial Catalog=Awesome_Dev;Integrated Security=True"/>
  <add name="MyApp_Prod" connectionString="Data Source=SQL071;Initial Catalog=Awesome_Dev;Integrated Security=True"/>
</connectionStrings>

appSettings.config:

<appSettings>
  <add key="CompanyName" value="The Awesome Company"/>
  <add key="PhoneNumber" value="(513) 555-4444"/>
</appSettings>

Then, point to these files in the app.config, as shown below:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings configSource="connections.config" />
  <appSettings configSource="appSettings.config" />
</configuration>
One caveat to doing this: The configSource files (connections.config and appSettings.config in our example) must be in the same folder as the config file. We can accomplish this by selecting each configSource file in Solution Explorer and setting its Copy to Output directory property to either “Copy always” or “Copy if newer”.
Friday, 25 May 2012 15:19:00 (GMT Daylight Time, UTC+01:00)
# Thursday, 24 May 2012

Here is Phil Japikse’s presentation on Testing Code From The Pit of Despair at the March 2012 Great Lakes Area .NET User Group (GANG).

Thursday, 24 May 2012 17:06:00 (GMT Daylight Time, UTC+01:00)
# Monday, 21 May 2012
Monday, 21 May 2012 17:06:00 (GMT Daylight Time, UTC+01:00)