Some key points to remember on Threading

January 30, 2008 by

Here are some key points that I’ve found while going through the Threading chapter.

  1. To perform work concurrently, use the Thread class.
  2. To start thread execution, use the Thread class’s Start method.
  3. To wait on threads to complete, use the Thread class’s Join method.
  4. To cancel execution of a thread, use the Thread class’s Abort method.
  5. To share data across threads, use the ExecutionContext class.
  6. To perform atomic math operations, use the Interlock class.
  7. To lock data, use the C# lock or the Visual Basic SyncLock syntax.
  8. To lock data with a synchronization object, use the Monitor class.
  9. To lock data where multiple readers can access data at once but one writer at a time can change data, use a ReaderWriterLock.
  10. To synchronize threads across AppDomains or process boundaries, use a Mutex.
  11. To throttle threads with a resource-based synchronization object, use a Semaphore.
  12. To signal threads across AppDomains or process boundaries, use an Event.
  13. The Thread class can be used to create multiple paths for simultaneous execution in your own applications.
  14. Using the lock (SyncLock in Visual Basic) keyword will allow you to write threadsafe access to your code’s data.
  15. You must be careful in writing thread-safe code to avoid deadlock situations.
  16. The ReaderWriterLock class can be used to write thread-safe code that is less prone to allowing only a single thread at a time to access its data.
  17. The WaitHandle derived classes (Mutex, Semaphore, and Event classes) exemplify Windows operating-system-level synchronization objects.
  18. Much of the .NET Framework supports the Asynchronous Programming Model (APM) to allow for asynchronous execution of code without having to directly deal with the ThreadPool or Threads.
  19. The ThreadPool is a convenient class that enables fast creation of threads for queuing up code to run as well as for waiting for WaitHandle derived objects.
  20. Timers are useful objects for firing off code on separate threads at specific intervals.

Extracted from MCTS(70-536) Application Development Foundation

Quick Walkthrough of Collections and Genrics

January 23, 2008 by


The .NET Framework supports a variety of collection classes that can be used in different circumstances. Here are some points that give a quick summary of Collections and Genrics in framework 2.0

Basics

  1. The ArrayList is a simple collection of unordered items.
  2. The Add and AddRange methods of the ArrayList are used to add items to an ArrayList.
  3. The Insert and InsertRange methods of the ArrayList are used to insert items into specific places in a collection.
  4. The Remove, RemoveAt, and RemoveRange methods of the ArrayList are used to delete items from a collection.
  5. The indexer of the ArrayList can be used to iterate over a collection.
  6. The IEnumerable and IEnumerator interfaces can be used to enumerate through a collection as well.
  7. The foreach construct in Visual Basic and C# use the IEnumerable interface to concisely iterate over a collection.

Sequential Lists

  1. The .NET Framework supports the Queue and Stack classes to provide collections that represent sequential lists of items.
  2. The Queue is a first-in, first-out (FIFO) collection.
  3. The Queue class supports the Enqueue and Dequeue methods for adding and removing items from the collection.
  4. The Stack is a last-in, first-out (LIFO) collection.
  5. The Stack class supports the Push and Pop methods for adding and removing items, respectively, from the collection.
  6. Both sequential collection classes support Peek for viewing the next item in the collection without removing it.

Dictionaries

  1. The IDictionary interface provides the basic calling convention for all Dictionary collections.
  2. The Hashtable class can be used to create lookup tables.
  3. You can use a DictionaryEntry object to get at the key and value of an object in a Dictionary collection.
  4. The SortedList can be used to create list of items that can be sorted by a key.
  5. The IEqualityComparer can be used to construct hash values and compare values for classes in an arbitrary way.

Specialized Collections

  1. The BitArray class and the BitVector32 structure can both be used to perform bit-wise operations on a series of Boolean values.
  2. The StringCollection and StringDictionary classes are type-safe classes for storing strings.
  3. You can create case-insensitive versions of Hashtable and SortedList objects using the CollectionUtil class.
  4. NameValueCollection is a useful class for storing more than one value per key in a name/value collection.

Generic Collections

  1. Generic collections can be used to create more type-safe and potentially faster versions of their nongeneric counterparts.
  2. The generic List, Dictionary, Queue, Stack, SortedList, and SortedDictionary classes are type-safe versions of the collections.
  3. The new LinkedList generic class is a collection for storing items that know about their own relationship in the list, and it allows for iteration without having access to the collection itself.

Combine Delegates (Multicast Delegates)

January 21, 2008 by

This example demonstrates how to compose multicast delegates. A useful property of delegate objects is that they can be assigned to one delegate instance to be multicast using the + operator. A composed delegate calls the two delegates it was composed from. Only delegates of the same type can be composed.

 

The - operator can be used to remove a component delegate from a composed delegate.

 

Example

delegate void Del(string s);

class TestClass
{
    static void Hello(string s)
    {
        System.Console.WriteLine("  Hello, {0}!", s);
    }

    static void Goodbye(string s)
    {
        System.Console.WriteLine("  Goodbye, {0}!", s);
    }

    static void Main()
    {
        Del a, b, c, d;

        // Create the delegate object a that references 
        // the method Hello:
        a = Hello;

        // Create the delegate object b that references 
        // the method Goodbye:
        b = Goodbye;

        // The two delegates, a and b, are composed to form c: 
        c = a + b;

        // Remove a from the composed delegate, leaving d, 
        // which calls only the method Goodbye:
        d = c - a;

        System.Console.WriteLine("Invoking delegate a:");
        a("A");
        System.Console.WriteLine("Invoking delegate b:");
        b("B");
        System.Console.WriteLine("Invoking delegate c:");
        c("C");
        System.Console.WriteLine("Invoking delegate d:");
        d("D");
    }
}

Output

Invoking delegate a:
  Hello, A!
Invoking delegate b:
  Goodbye, B!
Invoking delegate c:
  Hello, C!
  Goodbye, C!
Invoking delegate d:
  Goodbye, D!

Extracted from MSDN articles

 

When to Use Delegates Instead of Interfaces

January 21, 2008 by
Both delegates and interfaces enable a class designer to separate type declarations and implementation. A given interface can be inherited and implemented by any class or struct. A delegate can be created for a method on any class, as long as the method fits the method signature for the delegate. An interface reference or a delegate can be used by an object that has no knowledge of the class that implements the interface or delegate method. Given these similarities, when should a class designer use a delegate and when should it use an interface?
Use a delegate in the following circumstances:
  • An eventing design pattern is used.
  • It is desirable to encapsulate a static method.
  • The caller has no need to access other properties, methods, or interfaces on the object implementing the method.
  • Easy composition is desired.
  • A class may need more than one implementation of the method.

Use an interface in the following circumstances:

  • There is a group of related methods that may be called.
  • A class only needs one implementation of the method.
  • The class using the interface will want to cast that interface to other interface or class types.
  • The method being implemented is linked to the type or identity of the class: for example, comparison methods.

One good example of using a single-method interface instead of a delegate is IComparable or the generic version, IComparable(T). IComparable declares the CompareTo method, which returns an integer that specifies a less than, equal to, or greater than relationship between two objects of the same type. IComparable can be used as the basis of a sort algorithm. Although using a delegate comparison method as the basis of a sort algorithm would be valid, it is not ideal. Because the ability to compare belongs to the class and the comparison algorithm does not change at run time, a single-method interface is ideal.

Extracted from Microsoft Technet articles.

SQL Bulk copy

January 14, 2008 by

Very straightforward with C# .Net 2005 !

The important class is “SqlBulkCopy”.

“SqlBulkCopy” is very helpful in coping the contents of one database table to other.

I ensured that the design of the table is same. I used Customers table of Northwind database (created a copy of it named CustomersHistory) and my both DesitnationConnection and SourceConnection points to same database.

Few lines below is all that is needed:

// SourceConnection and DestinationConnection are a SqlConnection pointing to Northwind database

// Data from Customers table is bulk-copied to CustomersHistory

SqlCommand GetCustomerCommand = new SqlCommand(“SELECT * FROM Customers”,SourceConnection);
SourceConnection.Open();
SqlDataReader CustomerReader = GetCustomerCommand.ExecuteReader();
SqlBulkCopy CustomerBulkCopy = new SqlBulkCopy(DestinationConnection);
DestinationConnection.Open();
CustomerBulkCopy.DestinationTableName = “CustomerHistory”;
CustomerBulkCopy.WriteToServer(CustomerReader);
CustomerReader.Close();
DestinationConnection.Close();
SourceConnection.Close();

// This code is taken from MCTS Self Paces Training Kit 526, with few changes

Folder Browser Dialog

January 14, 2008 by

Many time, it is necessary to show a folder browser dialog.

Typically this is useful in an GUI based application where the applications wants the user to choose a folder.

I came across FolderBrowserDialog.

FolderBrowserDialog SavePathDialog = new FolderBrowserDialog();
SavePathDialog.Description = "Select a folder to restore BLOB to";
SavePathDialog.ShowDialog();
String SavePath = SavePathDialog.SelectedPath;

MCTS(70-526) Windows-Based Client Development – Chapter 6 Summary

January 11, 2008 by

Chapter 6

Working with Data in a Connected environment

What Are Command Objects?

To execute SQL statements and stored procedures against a database (from your application), you use Command objects. Command objects contain the necessary information to execute SQL statements, stored procedures, functions, and so on against a data source; return data to your application; and perform database catalog operations such as creating, altering, and deleting database objects. In other words, you can use Command objects to execute any valid SQL statement.

Just like Connection objects, there are Command objects for each of the .NET Framework Data Providers. Select the specific Command object that coincides with the .NET Framework Data Provider being used to communicate with your data source.

The primary properties of a Command object are the CommandText, CommandType, and Connection properties.

Common Command Object Methods

Cancel

Tries to cancel the execution of the command.

ExecuteNonQuery

Executes SQL statements or stored procedures that do not return data.

ExecuteReader

Executes commands that return tabular (or rows) of data.

ExecuteScalar

Executes SQL statements or stored procedures that return a single value. If you call ExecuteScalar with a statement that returns rows of data, the query executes but returns only the first column of the first row returned by the query. Additional columns or rows are ignored.

ExecuteXMLReader

Returns XML formatted data. Returns a System.Xml.XmlReader object.

Creating and Configuring Command Objects

Create Command objects by declaring an instance of the desired Command object and setting the CommandType and CommandText properties. To execute the command, you must also set the command’s Connection property to a valid Connection object.

Creating a Command Object That Executes a SQL Statement

To execute commands that run SQL statements against a database, set the CommandType property to Text and set the CommandText property to the SQL statement you want to execute.

SqlCommand CustomersCommand = new SqlCommand();

CustomersCommand.Connection = NorthwindConnection;

CustomersCommand.CommandType = CommandType.Text;

CustomersCommand.CommandText = “SELECT CustomerID, CompanyName FROM Customers”;

Creating a Command Object That Executes a Stored Procedure

To execute commands that run existing stored procedures in a database, set the CommandType property to StoredProcedure and set the CommandText property to the name of the stored procedure you want to execute.

SqlCommand TopTenCommand = new SqlCommand();

TopTenCommand.Connection = NorthwindConnection;

TopTenCommand.CommandType = CommandType.StoredProcedure;

TopTenCommand.CommandText = “Ten Most Expensive Products”;

Creating a Command Object That Performs Catalog Operations

To execute commands that run DML actions (Data Manipulation Language), create commands that run SQL statements and call the ExecuteNonQuery method of the command.

SqlCommand CreateTableCommand = new SqlCommand();

CreateTableCommand.Connection = NorthwindConnection;

CreateTableCommand.CommandType = CommandType.Text;

CreateTableCommand.CommandText = “CREATE TABLE SalesPersons (” +

“[SalesPersonID] [int] IDENTITY(1,1) NOT NULL, ” +

“[FirstName] [nvarchar](50) NULL, ” +

“[LastName] [nvarchar](50) NULL)”;

// ExecuteNonQuery to be done later

Creating a Command Object That Returns a Single Value

To execute commands that return single values (scalar values), create commands that run SQL statements or stored procedures that return a single value (as opposed to commands that return rows or tabular data). Set the CommandText property to a SQL statement or stored procedure that returns a single value and call the ExecuteScalar method of the command. Declare a variable with the data type of the single value being returned from the database and cast the results of the ExecuteScalar call to the expected data type. (The ExecuteScalar method returns an Object, so you must cast the ExecuteScalar method to the equivalent of the returned data type.)

// C#

SqlCommand ExecuteScalarCommand = new SqlCommand();

ExecuteScalarCommand.Connection = NorthwindConnection;

ExecuteScalarCommand.CommandType = CommandType.Text;

ExecuteScalarCommand.CommandText = “SELECT Count(*) FROM Customers”;

// Open the connection and execute the command

ExecuteScalarCommand.Connection.Open();

int CustomerCount = (int)ExecuteScalarCommand.ExecuteScalar();

MessageBox.Show(“There are ” + CustomerCount.ToString() + ” customers”); ExecuteScalarCommand.Connection.Close();

Executing Commands Asynchronously

Executing commands asynchronously is the process of having the command execute on a separate thread from the rest of your application so users do not have to wait for the command to complete before continuing work in other parts of the application.

BeginExecuteNonQuery

Starts the asynchronousl version of ExecuteNonQuery

BeginExecuteReader

Starts the asynchronous version of the ExecuteReader method.

BeginExecuteXmlReader

Starts the asynchronous version of the ExecuteXmlReader method.

EndExecuteNonQuery

Call this method after the StatementComplete event fires to complete execution of the command.

EndExecuteReader

Call this method after the StatementComplete event fires to return the DataReader with the data returned by the command.

EndExecuteXMLReader

Call this method after the StatementComplete event fires to return the XmlReader with the data returned by the command.

When executing commands asynchronously, you explicitly call the Begin and End methods of the selected Command object. Calling the Begin method sends the command (SQL statement or stored procedure call) to the database, and then you can perform other operations in your application. When the command finishes executing, the StatementCompleted event fires, notifying the application that it can call the End method of the command and access the data for further processing.

// C#

System.Text.StringBuilder results = new System.Text.StringBuilder();

SqlConnection NorthWindConnection = new SqlConnection(“Data Source=.\\;Initial Catalog=Northwind;” +

“Integrated Security=True; asynchronous processing = true“);

SqlCommand command1 = new SqlCommand(“WAITFOR DELAY ’00:00:05′; ” +

Select * From [Order Details]“, NorthWindConnection);

NorthWindConnection.Open();

IAsyncResult r = command1.BeginExecuteReader();

MessageBox.Show(“The command has been executed but processing is free ” + “to display this message before the results have been returned!”);

SqlDataReader reader = command1.EndExecuteReader(r);

while (reader.Read())

{

for (int i = 0; i< reader.FieldCount – 1; i++)

{

results.Append(reader[i].ToString() + “\t”);

}

results.Append(Environment.NewLine);

}

reader.Close();

command1.Connection.Close();

MessageBox.Show(results.ToString());

Executing Multiple SQL Statements Using a DataReader

In addition to returning the results from a single SQL statement, you can use a Command object and DataReader to return the results of multiple SQL statements. To execute more than one SQL statement, set the CommandText property of a Command object to multiple SQL statements separated by semicolons (;). After calling the ExecuteReader method, the DataReader will hold the number of result sets equal to the number of SQL statements executed. To access the data returned by the additional statements, call the NextResult method of the DataReader.

ExecuteSqlCommand.CommandText = “SELECT CustomerID, CompanyName FROM Customers; SELECT ProductName, UnitsInStock FROM Products”;

SqlDataReader reader = ExecuteSqlCommand.ExecuteReader();

bool MoreResults = false;

do

{

while (reader.Read())

{

for (int i = 0; i < reader.FieldCount; i++)

{

results.Append(reader[i].ToString() + “\t”);

}

results.Append(Environment.NewLine);

}

MoreResults = reader.NextResult();

} while (MoreResults);

Working with Parameters in SQL Commands

A parameter can be thought of as a type of variable that you can use to pass and return values between your application and a database. Just like a variable in your application, parameters are created to contain a certain data type. Parameter data types are assigned using the types defined in the System.Data.SqlDbType enumeration. The SqlDbType enumeration contains a list of the types available in SQL Server as opposed to application variables that are typically assigned one of the .NET Framework base data types.

Types of Parameters

When executing Command objects, you typically use parameters to send data to the database. This type of parameter is referred to as an Input parameter. In addition to Input parameters, you might also want to use a parameter to retrieve information coming out of the database; this type of parameter is called an Output parameter. There is also a third type of parameter, which is referred to as an InputOutput parameter. InputOutput parameters are used to both send and receive data when executing a command. The type of parameter is designated in the Direction property of the parameter and is assigned a value from the ParameterDirection enumeration. In other words, when creating a parameter, you can set its Direction property to Input, Output, InputOutput, or ReturnValue.

Parameters are Input type by default.

Creating Parameters

Create parameters by declaring an instance of the Parameter class and setting its name and data type to coincide with the parameter name and data type expected by the data source. You can also set the parameter’s ParameterDirection property to choose the type of parameter to create.

SqlParameter TotalCostParameter = new SqlParameter();

TotalCostParameter.ParameterName = “@TotalCost”;

TotalCostParameter.SqlDbType = SqlDbType.Money;

Adding Parameters to Command Objects

GetCostCommand.Parameters.Add(TotalCostParameter);

Saving and Retrieving BLOB Values in a Database

BLOBs in a database are more complex than simple strings containing names and addresses or numeric values containing integers or money values. BLOBs are things like graphics and photos, documents saved in binary formats, and even complete assemblies or executables that you want to store in a database.

Working with BLOBs

Saving and fetching binary data presents interesting problems that are typically not encountered when querying standard rows of data. The problems arise because you will probably not want to move the entire BLOB in one piece but will likely need to break it up into smaller portions. For example, consider having to move a large binary that is several megabytes in size. Loading the entire BLOB into a variable consumes a lot of memory and can seriously affect the performance of your application. Having to work with a table of these BLOBs, you can quickly see the dilemma.

The good thing is that the .NET Framework provides classes that are specifically designed for moving large amounts of binary data. Specifically, access to these classes—for example, the BinaryReader and BinaryWriter classes, the FileStream and MemoryStream classes, and so on—is enabled in the System.IO namespace. Although this lesson does not use all the available stream objects, it should provide enough of a starting point to understand the basics of saving and fetching binary data from a database.

BLOBs and the DataReader

By setting its CommandBehavior to SequentialAccess, you can then call the GetBytes method, which allows you to read the data in smaller, user-definable amounts. The bytes that make up a BLOB are transported in and out of the database to your application using byte arrays.

MCTS(70-526) Windows-Based Client Development – Chapter 5 Summary

January 11, 2008 by

Chapter 5

Configuring connections and connecting to data

What is ADO.Net?

When creating applications that work with data, the Microsoft .NET Framework provides many classes that aid in the process. The classes that you use for common data tasks such as communicating, storing, fetching, and updating data are all located in the System.Data namespace. The classes in the System.Data namespace make up the core data access objects in the .NET Framework. These data access classes are collectively known as ADO.NET.

What is a Connection object?

A connection object is simply a representation of an open connection to a data source.

A connection object does not fetch or update data, it does not execute queries, and it does not contain the results of queries; it is merely the pipeline that commands and queries use to send their SQL statements and receive results.

Connection events

Connection objects provide the StateChanged and InfoMessage events to provide information to your application regarding the status of the database and information pertaining to commands executed using a specific connection object.

StateChanged Event

This event is raised when the current state of the database changes from Open to Closed.

InfoMessage Event

In addition to monitoring the state of a connection, each connection object provides an InfoMessage event that is raised when warnings or messages are returned from the server. Informational messages are typically provided when low-severity errors are returned by the data source that the connection object is connected to. For example, SQL Server errors with a severity of 10 or less are provided to the InfoMessage event.

What Is Connection Pooling?

Connection pooling enables the reuse of existing connections to reduce the overhead of continuously creating and disposing of connections that have the same configuration. In other words, opening and closing connections that use the same connection string and credentials can reuse a connection that is available in the pool.

Connection pools are separated by process, application domain, and connection string. For connection strings that use integrated security, a separate pool is created for each unique identity

Controlling connection pooling

Connection pooling is enabled by default when creating ADO.NET connection objects. You can control connection pooling behavior (or disable pooling altogether) by setting connection string keywords specific to connection pooling. For example, to specifically disable connection pooling, you set Pooling=False in your connection string

Connection Lifetime

0

When a connection is returned to the pool, if its creation time was longer than x seconds ago, with x being the value of this property, then the connection is destroyed. Values are in seconds, and a value of 0 indicates the maximum connection timeout.

Connection Reset

True

Determines whether the database connection is reset when being drawn from the pool. For SQL Server 7.0, setting to False avoids making an additional server round trip when obtaining a connection, but the connection state, such as database context, is not being reset.

Enlist

True

If you want to use a connection as part of a transaction you can set this to True and the pooler will automatically enlist the connection in the creation thread’s current transaction context.

Load Balance Timeout

0

The minimum number of seconds for the connection to live in the connection pool before being destroyed.

Max Pool Size

100

The maximum number of connections allowed in the pool for this specific connection string. In other words if your application continuously connects to the database you might need to increase the Max Pool Size. For example, if your application has many users that all use the same connection string and there is the possibility of needing more than 100 connections you would want to increase the Max Pool Size, this may occur when many users are accessing the database server using a common client or Web page.

Min Pool Size

0

The minimum number of connections allowed in the pool.

Pooling

True

When true, the SqlConnection object is drawn from the appropriate pool or, if it is required, is created and added to the appropriate pool. Recognized values are True, False, Yes, and No.

Handling connection errors

When SQL Server returns a warning or an error, the .NET Framework Data Provider for SQL Server creates and throws a SqlException that you can catch in your application to deal with the problem. When SqlException is thrown, inspect the SqlException.Errors property to access the collection of errors that are returned from the SQL server. The SqlException.Errors property is a SqlErrorCollection class (a collection of SqlError classes) that always contains at least one SqlError object.

SqlConnection will remain open for messages with a severity level of 19 and below, but it will typically close automatically when the severity is 20 or greater.

catch (SqlException ex)

{

string errorMessage = “”;

foreach (SqlError ConnectionError in ex.Errors)

{

errorMessage += ConnectionError.Message + ” (error: ” +

ConnectionError.Number.ToString() + “)” + Environment.NewLine;

if (ConnectionError.Number == 18452)

{

MessageBox.Show(“Invalid Login Detected, please provide valid credentials!”);

}

}

MessageBox.Show(errorMessage);

}

finally

{

connection.Close();

}

Enumerating the available SQL Servers on a network

The .NET Framework offers applications a way to discover SQL Server instances on a network so your programs can process this information when necessary. To retrieve the list of available SQL Servers, use the Instance property of the SqlDataSourceEnumerator class and call the GetDataSources method. The GetDataSources method returns a Data-Table that contains information for each SQL server that is visible on the network. The returned data table contains the columns

ServerName

Name of the SQL server containing the visible instance

InstanceName

Name of the server instance or empty for servers running default instances

IsClustered

Indicates whether the server is part of a cluster

Version

The version number of the SQL server

Why Do Only Some or No SQL Servers Appear in My Grid?

Depending on how your network or even single machine is set up, the list of available servers may or may not be complete. In addition to things such as network traffic and timeout issues, the way your network implements security can cause servers to be hidden from the returned list as well. If you are running SQL Server 2005, there is a service named SQL Browser that needs to be running to see SQL Server instances. And even if your SQL Browser service is running, your firewall may be blocking the request for SQL information; the firewall is likely to be blocking communication requests through port 1433, which is the default port that SQL Server default instances are set up to use

Securing sensitive connection string data

The suggested method of implementing security in applications that access data is to use Windows Authentication (also known as Integrated Security). To further protect sensitive connection information when using Integrated Security, it is also recommended that you set the Persist Security Information keyword to False in the connection string. This ensures that the credentials used to open the connection are discarded and not stored where someone might be able to retrieve them.

Do not store the connection string in the compiled application. As an alternative, you can use the application configuration file (app.config). The app.config file stores connection strings as XML, and your application gets its connection information by querying this file at run time (as opposed to compiling the connection string into the application itself). By default the application configuration file stores it’s information unencrypted

The suggested approach to encrypting configuration data is to use a protected-configuration provider. There are two protected-configuration providers available in the .NET Framework as well as a base class you can use to implement your own if the two available providers are not sufficient for your application.

Encrypt:

string provider = “DataProtectionConfigurationProvider”;

//Encrypt the connectionStrings

ConfigurationSection connstrings = config.ConnectionStrings; connstrings.SectionInformation.ProtectSection(provider);

connstrings.SectionInformation.ForceSave = true;

config.Save(ConfigurationSaveMode.Full);

Decrypt:

// Decrypt the connectionStrings

ConfigurationSection connstrings = config.ConnectionStrings; connstrings.SectionInformation.UnprotectSection();

connstrings.SectionInformation.ForceSave = true;

config.Save(ConfigurationSaveMode.Full);

Encripting the Application Settings

January 11, 2008 by

I learned something new today!

In C# .Net 2005, an application required configuration information can be saved with Settings available in the Project,->Properties

I think saving settings here are better than saving in Registry or creating a separate XML file for very trivial tasks.

I wanted to encrypt this file and was searching for good approaches.

I added couple of Settings with both Application and User scope using the IDE. (See the attached image ‘Settings.JPG’).
Setting

The configuration file is generated after the Build and I have attached image (‘Original.JPG’)

Few lines of code and the file can be encrypted. See attached image (‘Encrypted.JPG’)

(Add System.Configuration in Reference)

The code for Encryption:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
string provider = “DataProtectionConfigurationProvider”;
//userSettings
ConfigurationSectionGroup group = config.GetSectionGroup(“userSettings”);
ConfigurationSection section = group.Sections[0];
section.SectionInformation.ProtectSection(provider);

//applicationSettings
group = config.GetSectionGroup(“applicationSettings”);
section = group.Sections[0];
section.SectionInformation.ProtectSection(provider);

section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);

Decryption:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

//userSettings
ConfigurationSectionGroup group = config.GetSectionGroup(“userSettings”);
ConfigurationSection section = group.Sections[0];
section.SectionInformation.UnprotectSection();

//applicationSettings
group = config.GetSectionGroup(“applicationSettings”);
section = group.Sections[0];
section.SectionInformation.UnprotectSection();

section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);

OriginalEncrypted


Follow

Get every new post delivered to your Inbox.