Solved

How to read connection string from outside my application folder?

Posted on 2014-10-03
17
736 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 74

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 74

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
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
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.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

707 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

13 Experts available now in Live!

Get 1:1 Help Now