Solved

How to read connection string from outside my application folder?

Posted on 2014-10-03
17
801 Views
Last Modified: 2014-10-12
i am working on the c# windows application.
And I am not reading connectionstring from app.config file in my application folder  instead I need to get the connection string from outside my application. This app.config file is in c:\myapp\common\ folder but my application folder is in c:\myapp\crm\ folder. How to read this config.file ?

config file
?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
    
  	<connectionStrings>
   <clear/>
      
       <add name="myCommondb" connectionString="Data Source=ltp;Initial Catalog=db1;Persist Security Info=True;User ID=john;Password=abcd1234wert" providerName="System.Data.SqlClient" />
  </connectionStrings>
  
</configuration>

Open in new window

0
Comment
Question by:Varshini S
  • 8
  • 7
  • 2
17 Comments
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40361230
Hi Rubha;

You can place the the connection string in a external configuration file which will only contain connectionStrings node and nothing else. The main app.config will have the path and file name of this external file. Please see this Microsoft documentation in the section called "Using External Configuration Files" on how to set it up.

Connection Strings and Configuration Files
0
 

Author Comment

by:Varshini S
ID: 40361316
I have mapped the configuration file path in my application configuration file.


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings configSource="C:\Program Files (x86)\TEST\Connection.exe.config">  </connectionStrings>
      <configSections>
    </configSections>
   </configuration>

But it is showing following exception:
Configuration system failed to initialize
The configSource attribute must be a relative physical path.
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40361429
Well it appears that the external configuration file must be in a sub directory of the application using it. I tried one directory above did not work I then tried one directory below and it worked fine. I do not know what Microsoft was thinking when they did this restriction.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 40361432
You can use the mklink command to create a symbolic (or hard) link to the file/directory from within your application's directory. Then the config system should pick it up.
0
 

Author Comment

by:Varshini S
ID: 40361460
Fernando : You are correct  but for me even in the sub directory I did not work.
Kaufmed:  mklink command does not support for windows 7 . Am I correct ?
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40361474
Hi Varshini;

Lets say that you want to place the file Connection.exe.config in the sub directory config then change this line in app.config

<connectionStrings configSource="C:\Program Files (x86)\TEST\Connection.exe.config">

to this

<connectionStrings configSource="config\\Connection.exe.config">
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 40361575
Yes, it works on Win 7.

@Fernando

That should be a single slash in the 2nd one.
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40361589
Tanks kaufmed it was my fingers double tapping the key in error.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:Varshini S
ID: 40367120
Instead, can I read  XML file and assign the values in the run time ?
 
?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
    
  	<connectionStrings>
   <clear/>
      
       <add name="myCommondb" connectionString="Data Source=ltp;Initial Catalog=db1;Persist Security Info=True;User ID=john;Password=abcd1234wert" providerName="System.Data.SqlClient" />
  </connectionStrings>
  
</configuration>

Open in new window

0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40367195
Hi Varshini;

In answer to your question yes you can read in an XML document into your program and retrieve the connection string information. But the XML you gave has more information then just the connection string. If this is the app.config file and you also wish to process the other nodes that would normally be processed by the application then you may not be able to do that. for example if you have a node like this:

    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>

Open in new window


You may have issues. But just getting the data for your own use is not a problem. Other issues to think about is how will you tell the program where the xml file is located at. You could set a user string variable in the properties page of the application but that setting is stored in the app.config file. Which is not a problem technically. Or you could pass it in on the command line. But what you do not want to do is hard code it because anytime you want to change the location of the XML file you will need to re-compile the program.

Let me know what you want to do and I can write up some sample code.
0
 

Author Comment

by:Varshini S
ID: 40367269
Fernando,
Thank You for the update. I would like to keep path of the XML file in the app.config file. In my application even after the deployment app.config is editable. I am going to keep the following XML file. The connection string information
encrypted with Triple Data Encryption Algorithm. In the run time I need to decrypt this connection string.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <connectionStrings>
      <clear/>
      <add name="Encrypted"
             providerName="System.Data.SqlClient"
             connectionString="mcQKhSSzcMP9199vA8Bod1/y6VJrZNL3m4AQiDHwonHyuSUctBQY/cgOz5rakHa2d5mVKSSxdE2RjDDB0DxKUsoWbddaeej6ufY6fUj6ACmwJQyiB+I3OA=="
		/>
    </connectionStrings>
    </configuration>

Open in new window


decrypted connection string is " Data Source=mysystem\SQLEXPRESS;Initial Catalog=MYDB;Persist Security Info=True;User ID=sa;Password=ABCD"

Please let me know , how to achieve this.
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40367284
Please post the code you used to encrypt the string.
0
 

Author Comment

by:Varshini S
ID: 40367288
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;

namespace TripleDESCryptoService
{
    class TripleDES
    {
                  
    // define the triple des provider 
    private TripleDESCryptoServiceProvider m_des = new TripleDESCryptoServiceProvider(); 
    
    // define the string handler 
    private UTF8Encoding m_utf8 = new UTF8Encoding(); 
    
    // define the local property arrays 
    private byte[] m_key; 
    private byte[] m_iv; 
    
    public TripleDES(byte[] key, byte[] iv) 
    { 
        this.m_key = key; 
        this.m_iv = iv; 
    } 
    
    public byte[] Encrypt(byte[] input) 
    { 
        return Transform(input, m_des.CreateEncryptor(m_key, m_iv)); 
    } 
    
    public byte[] Decrypt(byte[] input) 
    { 
        return Transform(input, m_des.CreateDecryptor(m_key, m_iv)); 
    } 
    
    public string Encrypt(string text) 
    { 
        byte[] input = m_utf8.GetBytes(text); 
        byte[] output = Transform(input, m_des.CreateEncryptor(m_key, m_iv)); 
        return Convert.ToBase64String(output); 
    } 
    
    public string Decrypt(string text) 
    { 
        try { 
            byte[] input = Convert.FromBase64String(text); 
            byte[] output = Transform(input, m_des.CreateDecryptor(m_key, m_iv)); 
            return m_utf8.GetString(output); 
        }
        catch { //(Exception ex)  
            return string.Empty; 
        } 
    } 
    
    private byte[] Transform(byte[] input, ICryptoTransform CryptoTransform) 
    { 
        // create the necessary streams 
        MemoryStream memStream = new MemoryStream(); 
        CryptoStream cryptStream = new CryptoStream(memStream, CryptoTransform, CryptoStreamMode.Write); 
        // transform the bytes as requested 
        cryptStream.Write(input, 0, input.Length); 
        cryptStream.FlushFinalBlock(); 
        // Read the memory stream and convert it back into byte array 
        memStream.Position = 0; 
        byte[] result = new byte[(int)memStream.Length - 1 + 1]; 
        memStream.Read(result, 0, (int)result.Length); 
        // close and release the streams 
        memStream.Close(); 
        cryptStream.Close(); 
        // hand back the encrypted buffer 
        return result; 
    } 
}

    }

Open in new window

0
 
LVL 62

Accepted Solution

by:
Fernando Soto earned 500 total points
ID: 40367534
Hi Varshini;

Well you have all the code you need to encrypt and decrypt the string. Create an instance of the TripleDES class. You will need a Key and IV to use which will be needed to encrypt and decrypt the string the Key and IV will need to be the same value for each operation so you will need to store it somewhere you can get to it when you go to decrypt the string. Without the Key and IV being the same values you used to encrypt the string you will not be able to decrypt it.

// Get the Key and IV byte array's from where you have stored them
byte[] key = ...;
byte[] iv = ...;

// Create an instance of the TripleDES class
// with the key and iv
TripleDES m_des = new TripleDES(key, iv);
// Convert the connection string to a byte array of characters
Byte[] data = Encoding.UTF8.GetBytes(connectionString);

encrypt the string
byte[] cripted = m_des.Encrypt(data);

// Write the byte array out to the app.config file

// To decrypt it is just the opposite, read the connection string from the app.config file and place into a byte array
byte[] cripted2 = ...;

// Decrypt the encrypted string
var decrited = td.Decrypt(cripted);
// Convert the decrited to a connection string
string cs = Encoding.UTF8.GetString(decrited);

// use cs to connect to the server

Open in new window

0
 

Author Comment

by:Varshini S
ID: 40367590
Fernando,
I am using following code to read the connection string. Does this help ?

XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(@"C:\Temp\Connection.exe.config");
            XmlNode nodestring = xmlDoc.SelectSingleNode("configuration");
            string urstring = nodestring.InnerXml;
0
 

Author Comment

by:Varshini S
ID: 40369338
Fernando,
 I got some solution to read the connection string from XML file.

I have question regarding the following code you provided.

// Write the byte array out to the app.config file

Instead of writing in to app.config file , is it possible to assign the connection string as global variable ?
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40369376
I'am sorry I got involved in putting out some fires here.

Well you will need to store the encrypted data so that when you need it you can recall it. A global variable will not  persist over terminating the program and restarting it. So you will need to save it somewhere and it does not need to be in a XML file.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
fomat Json objects 6 28
C# Single Form 8 27
C#  Radio button search for Date not DateTime 4 35
Reset asp.net login password 4 29
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now