Link to home
Start Free TrialLog in
Avatar of Varshini S
Varshini S

asked on

How to read connection string from outside my application folder?

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

Avatar of Fernando Soto
Fernando Soto
Flag of United States of America image

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
Avatar of Varshini S
Varshini S

ASKER

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.
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.
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.
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 ?
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">
Yes, it works on Win 7.

@Fernando

That should be a single slash in the 2nd one.
Tanks kaufmed it was my fingers double tapping the key in error.
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

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.
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.
Please post the code you used to encrypt the string.
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

ASKER CERTIFIED SOLUTION
Avatar of Fernando Soto
Fernando Soto
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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;
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 ?
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.